我创建了一个快捷Attached Property
方式,可以让您坚持使用 MVVM 概念,还可以让您滚动到DataGrid
. 它可以改进(例如,避免使用两个单独的属性并使用 anIValueConverter
来决定如何滚动),但这应该会给你一个很好的起点。
首先,我们创建附加属性(一个用于滚动到底部,一个用于顶部)
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;
}
那应该行得通。如前所述,您可能可以对其进行改进以避免重置代码,但希望这可以提供一个想法。