如何使用MVVM获取WPF数据网格的可视化子级?

如何使用MVVM获取WPF数据网格的可视化子级?,mvvm,wpfdatagrid,Mvvm,Wpfdatagrid,视图具有一个数据网格,而视图模型具有以下功能 public DependencyObject ScrollViewer(DependencyObject targetControl) { if (targetControl is ScrollViewer) { return targetControl; } for (int i = 0; i < VisualTreeHelper.GetCh

视图具有一个数据网格,而视图模型具有以下功能

public  DependencyObject ScrollViewer(DependencyObject targetControl)
    {
        if (targetControl is ScrollViewer)
        {
            return targetControl;
        }

        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(targetControl); i++)
        {
            var child = VisualTreeHelper.GetChild(targetControl, i);
            var result = ScrollViewer(child);
            if (result == null)
            {
                continue;
            }
            else
            {
                return result;
            }
        }
        return null;
    }

如果我将datagrid id作为参数传递。我会得到结果的。但这在MVVM模式中是不可能的。有什么方法可以获得可视化的子数据网格吗?

我创建了一个快速的
附加属性
,该属性应允许您坚持MVVM概念,并提供滚动到
数据网格的顶部和底部的能力。可以对其进行改进(例如,避免使用两个单独的属性,并使用
IValueConverter
来决定如何滚动),但这应该为您提供一个良好的起点

首先,我们创建附加属性(一个用于滚动到底部,另一个用于顶部)

然后,我们可以将属性附加到我们的
DataGrid

<DataGrid custom:Scroller.ScrollToBottom="{Binding ScrollBottom}" custom:Scroller.ScrollToTop="{Binding ScrollTop}" ...?
最后处理按钮(我猜您使用的是
ICommands
)来调用滚动

private void ScrollBottomCommand(object param)
{
    //Immediately set back to false so that it can be reused
    ScrollBottom = true;
    ScrollBottom = false;
}

private void ScrollTopCommand(object param)
{
    ScrollTop = true;
    ScrollTop = false;
}

这应该行得通。如前所述,您可能可以对其进行改进,以避免重置代码,但希望这会给出一个想法。

我创建了一个快速的
附加属性
,该属性应允许您坚持MVVM概念,并提供滚动到
数据网格的顶部和底部的能力。可以对其进行改进(例如,避免使用两个单独的属性,并使用
IValueConverter
来决定如何滚动),但这应该为您提供一个良好的起点

首先,我们创建附加属性(一个用于滚动到底部,另一个用于顶部)

然后,我们可以将属性附加到我们的
DataGrid

<DataGrid custom:Scroller.ScrollToBottom="{Binding ScrollBottom}" custom:Scroller.ScrollToTop="{Binding ScrollTop}" ...?
最后处理按钮(我猜您使用的是
ICommands
)来调用滚动

private void ScrollBottomCommand(object param)
{
    //Immediately set back to false so that it can be reused
    ScrollBottom = true;
    ScrollBottom = false;
}

private void ScrollTopCommand(object param)
{
    ScrollTop = true;
    ScrollTop = false;
}

这应该行得通。如前所述,您可能会对其进行改进以避免重置代码,但希望这会给出一个想法。

一般来说,您不应该将视图元素传递给ViewModel,因为这样做的目的是分离这两个关注点。你想做什么?不使用mvvm模式,我可以通过在ScrollViewer()函数中传递数据网格的id来获得数据网格的可视子级。但我不知道,如何在mvvm模式中实现这个场景。我理解这一点,但为什么您要尝试获取可视化子对象本身?您不能将相关命令和绑定添加到可视化子级并将其连接到您的ViewModel吗?我需要获取数据网格的滚动查看器。然后我将使用一些函数来处理滚动。根据您希望遵守MVVM的严格程度,您可以在您的查看代码中执行此操作,并将事件处理程序附加到您的VM以控制滚动(这与直接混合VM和查看不同)。有些人可能对此不满意(那些根本不想在视图中显示代码的人),在这种情况下,您可以创建一个
附加属性
,并将其分配给您的ScrollViewer。此属性可以访问ScrollViewer的滚动属性,然后您可以将其绑定到VM。一般来说,您不应该将视图元素传递给ViewModel,因为这样做的目的是分离这两个关注点。你想做什么?不使用mvvm模式,我可以通过在ScrollViewer()函数中传递数据网格的id来获得数据网格的可视子级。但我不知道,如何在mvvm模式中实现这个场景。我理解这一点,但为什么您要尝试获取可视化子对象本身?您不能将相关命令和绑定添加到可视化子级并将其连接到您的ViewModel吗?我需要获取数据网格的滚动查看器。然后我将使用一些函数来处理滚动。根据您希望遵守MVVM的严格程度,您可以在您的查看代码中执行此操作,并将事件处理程序附加到您的VM以控制滚动(这与直接混合VM和查看不同)。有些人可能对此不满意(那些根本不想在视图中显示代码的人),在这种情况下,您可以创建一个
附加属性
,并将其分配给您的ScrollViewer。此属性可以访问ScrollViewer的滚动属性,然后您可以将其绑定到VM。这是我所期望的。它正在工作。非常感谢你的努力。一种请求,我是MVVM模式的新手,有什么帮助吗?@ASHOKA-没问题!一开始可能会让人困惑,但你一定可以通过一些练习来理解它。这里有一些很好的教程链接,这是我所期待的。它正在工作。非常感谢你的努力。一种请求,我是MVVM模式的新手,有什么帮助吗?@ASHOKA-没问题!一开始可能会让人困惑,但你一定可以通过一些练习来理解它。这里有一些很好的教程链接
private bool _scrollBottom = false;
public bool ScrollBottom 
{
    get { return _scrollBottom; }
    set
    {
         _scrollBottom = value;                
         NotifyPropertyChanged("ScrollBottom");              
    }
}

private bool _scrollTop = false;
public bool ScrollTop
{
     get { return _scrollTop; }
     set
     {
          _scrollTop = value;
          NotifyPropertyChanged("ScrollTop");
     }
}
private void ScrollBottomCommand(object param)
{
    //Immediately set back to false so that it can be reused
    ScrollBottom = true;
    ScrollBottom = false;
}

private void ScrollTopCommand(object param)
{
    ScrollTop = true;
    ScrollTop = false;
}