视图有一个DataGrid, ViewModel 具有以下功能
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;
}
现在我想使用上面的函数获取网格的scrollviewer。
var scrolViewer = ScrollViewer(dataGridID) as ScrollViewer;
如果我将datagrid id作为参数传递。我会得到结果。但是在MVVM模式中是不可能的。有没有办法获得视觉子数据网格?
答案 0 :(得分:1)
我创建了一个快速Attached Property
,可以让您坚持使用MVVM概念,并且还可以滚动到DataGrid
的顶部和底部。它可以改进(例如,避免使用两个单独的属性并使用IValueConverter
来决定如何滚动),但这应该给你一个很好的起点。
首先,我们创建附加属性(一个用于滚动到底部,一个用于向上滚动)
public static class Scroller
{
//Create the attached property and register it
public static readonly DependencyProperty ScrollToBottomProperty =
DependencyProperty.RegisterAttached("ScrollToBottom", typeof(bool), typeof(Scroller), new PropertyMetadata(false, ScrollToBottomPropertyChanged));
//Create the get and set methods for the property
public static bool GetScrollToBottom(DependencyObject obj)
{
return (bool)obj.GetValue(ScrollToBottomProperty);
}
public static void SetScrollToBottom(DependencyObject obj, bool value)
{
obj.SetValue(ScrollToBottomProperty, value);
}
//Get the control that you've attached this to (DataGrid in this case) and find its ScrollViewer
private static void ScrollToBottomPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var scrollViewer = GetScrollViewer(d) as ScrollViewer;
if (scrollViewer != null && (bool)e.NewValue)
{
//Use built in ScrollToBottom method to scroll to...well...the bottom :)
scrollViewer.ScrollToBottom();
}
}
//Same as above but for "ScrollToTop" method
public static readonly DependencyProperty ScrollToTopProperty =
DependencyProperty.RegisterAttached("ScrollToTop", typeof(bool), typeof(Scroller), new PropertyMetadata(false, ScrollToTopPropertyChanged));
public static bool GetScrollToTop(DependencyObject obj)
{
return (bool)obj.GetValue(ScrollToTopProperty);
}
public static void SetScrollToTop(DependencyObject obj, bool value)
{
obj.SetValue(ScrollToTopProperty, value);
}
private static void ScrollToTopPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var scrollViewer = GetScrollViewer(d) as ScrollViewer;
if (scrollViewer != null && (bool)e.NewValue)
{
scrollViewer.ScrollToTop();
}
}
//Your ScrollViewerMethod (I renamed it to GetScrollViewer for clarity)
public static DependencyObject GetScrollViewer(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 = GetScrollViewer(child);
if (result == null)
{
continue;
}
else
{
return result;
}
}
return null;
}
}
在您的XAML中,您需要添加相关的命名空间(相应地更改您的命名空间)
xmlns:custom="clr-namespace:ScrollExampleMVVM"
然后我们可以将属性附加到DataGrid
<DataGrid custom:Scroller.ScrollToBottom="{Binding ScrollBottom}" custom:Scroller.ScrollToTop="{Binding ScrollTop}" ...?
在您的ViewModel中,您可以拥有公开的ScrollBottom
和ScrollTop
属性
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");
}
}
最后处理你的按钮(我猜你正在使用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;
}
那应该有用。如前所述,您可以改进它以避免重置代码,但希望这应该给出一个想法。