![](/img/trans.png)
[英]How do I bind controls to the selected item in a listbox using WPF and the MVVM pattern?
[英]WPF, how do I trigger ListBox.ScrollIntoView using MVVM pattern?
我有一个WPF应用程序,当用户按下按钮时,ListBox的内容就会更新。 我最初的问题是将ListBox重新聚焦到特定的SelectedIndex值,该值绑定到ViewModel中的ActiveItem属性。 我可以使用以下代码解决此问题:
XAML:
<ListBox ItemsSource="{Binding ListOfItems}" SelectedIndex="{Binding ActiveItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
IsSynchronizedWithCurrentItem="True" SelectionChanged="ListBox_SelectionChanged" x:Name="ListBoxSelector">
代码隐藏:
private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ListBoxSelector.ScrollIntoView(ListBoxSelector.SelectedItem);
}
但是,我目前在MainWindow.xaml.cs文件而不是ViewModel中具有上面的代码。 我的问题是如何将这段代码移至ViewModel,以便坚持使用MVVM模式? 我还不太清楚如何从ViewModel正确处理ListBox的ScrollIntoView属性。
您可以使用Behavior
类强制选定的项目滚动到视图中。
public class perListBoxHelper : Behavior<ListBox>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
}
protected override void OnDetaching()
{
AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
base.OnDetaching();
}
private static void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listBox = sender as ListBox;
if (listBox?.SelectedItem == null)
return;
Action action = () =>
{
listBox.UpdateLayout();
if (listBox.SelectedItem != null)
listBox.ScrollIntoView(listBox.SelectedItem);
};
listBox.Dispatcher.BeginInvoke(action, DispatcherPriority.ContextIdle);
}
}
有关我的博客文章的更多详细信息。
另外,我个人倒绑定到SelectedItem
的列表框,而不是SelectedIndex
,以及处理项目选择的任何处理该财产二传手,而不是使用事件处理程序。
MVVM模式不排除使用后面的代码。 实际上,这不可能,因为在某些情况下, 正确的做法是隐藏背后的代码。 视图模型是一个模型,不是视图替换。 另一种思考方式是,视图模型包含内容 ,而视图包含方式 。 至少,这是我对MVVM模式的解释。
在你的情况下,是什么项目的列表和当前项目。 该是怎样的ListBox
本身和它的默认行为。 在我看来,将选定的项目滚动到视图中是一种额外的行为,因此应保留在视图中。 因为你保持什么视图模型和如何在视图中你不违反MVVM模式。
我不确定我的解决方案是否为MVVM模式。但是对于这样的问题,它可以解决问题。
我将执行以下操作:如果按下Button,它将触发一个命令调用ViewModel中的方法。当ViewModel完成其工作时,viewModel会抛出一个自定义事件(其中包括列表框应滚动到的项目索引)。 在此之前,加载View时,View的Code-behind应该通过View的DataContext侦听其ViewModel,然后执行scrollIntoView。
就像我说的那样,我不确定这是否是MVVM,但是我认为这是可以接受的。
没有针对每个请求的通用解决方案,正如其他人提到的那样,MVVM并不意味着没有代码,但也没有多余的代码。
但是,如果您不想要任何代码,则可以在您的特定请求中找到解决方案-创建一个从ListView
继承并按需要处理请求的类,然后在XAML中使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.