WPF MVVM轻绑定到同一对象的多个ListBoxItem [英] WPF MVVM Light Multiple ListBoxItems bound to same object

查看:119
本文介绍了WPF MVVM轻绑定到同一对象的多个ListBoxItem的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含过程生成的ItemsControl的UserControl. ItemsControl中的每个项目都包含一个ListBox,并且没有将要生成多少个项目的一致数量.列表框中的所选项目绑定到ViewModel中的am对象(SelectedClass). SelectedClass对象的初始值为null.

I have UserControl containing a procedurally generated ItemsControl. Each item in the ItemsControl contains a ListBox and there is no consistent number of how many items will be generated. The selected item in the listbox is bound to am object (SelectedClass) in the ViewModel. The initial value of the SelectedClass object is null.

我遇到的情况是这样的:

The scenario I am running into is this:

  1. 用户从ItemsControlItemA中选择ListBoxItemA,激发PropertyChanged,将SelectedClass对象设置为适当的值.
  2. 然后用户从ItemsControlItemB中选择ListBoxItemA,激发PropertyChanged,将SelectedClass对象设置为适当的值.
  3. 然后,用户从ItemsControlItemA中选择ListBoxItemA,但是由于该列表中的选择仍被视为与步骤1中的项目相同,因此不会触发PropertyChanged,并且SelectedClass对象仍然是ItemsControlItemB中的ListBoxItemA.

所以我的问题是,如何获取UpdateSourceTrigger事件以触发OnClick而不是PropertyChanged,这甚至是处理该事件的最佳方法?我正在使用MVVM Light框架.

So my question is, how do i get the UpdateSourceTrigger event to fire OnClick rather than on PropertyChanged, and is that even the best way to approach it? I'm using the MVVM Light framework.

谢谢

<ItemsControl ItemsSource="{Binding AllUpcomingClasses}" >
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding classDescription}" />                    
                <ListBox Name="availableClasses"
                    ItemsSource="{Binding ClassInstances}" 
                    SelectedItem="{Binding
                                       DataContext.SelectedClass, 
                                       Mode=TwoWay}
                                       RelativeSource={RelativeSource 
                                           FindAncestor, 
                                           AncestorType={x:Type UserControl}}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <StackPanel>
                                <Grid>
                                    <TextBlock Text="{Binding ClassDate}" />
                                </Grid>
                            </StackPanel>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>                                    
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

对示例进行了一些整理以提高可读性.

Cleaned up the example a bit for readability.

推荐答案

如果单击的项目已被选中,则可以处理ListBoxItem容器的PreviewMouseLeftButtonDown事件,并手动"设置视图模型的SelectedItem属性. :

You could handle the PreviewMouseLeftButtonDown event of the ListBoxItem container and "manually" set the SelectedItem property of your view model if the clicked item is the one that is already selected:

<ListBox SelectedItem="{Binding SelectedItem}" xmlns:s="clr-namespace:System;assembly=mscorlib">
  <ListBox.ItemContainerStyle>
     <Style TargetType="ListBoxItem">
        <EventSetter Event="PreviewMouseLeftButtonDown" Handler="OnMouseLeftButtonDown"/>
     </Style>
  </ListBox.ItemContainerStyle>
  <s:String>A</s:String>
  <s:String>B</s:String>
  <s:String>C</s:String>
</ListBox>



private void OnMouseLeftButtonDown(object sender, MouseEventArgs e)
{
  ListBoxItem lbi = sender as ListBoxItem;
  if (lbi != null)
  {
    YourViewModel vm = DataContext as YourViewModel;
    if (vm != null)
    {
        var selectedItem = lbi.DataContext as YourObjectType;
        if (vm.SelectedItem == selectedItem)
        {
            vm.SelectedItem = selectedItem;
            e.Handled = false;
        }
    }
  }
}

如果您不想在视图的代码隐藏中处理此问题,则可以将相同的功能包装在附加的行为中:

If you don't want to handle this in the code-behind of the view you could wrap the same functionality in an attached behaviour: https://www.codeproject.com/articles/28959/introduction-to-attached-behaviors-in-wpf. The former approach doesn't really break the MVVM pattern though since you are just kind of "extending" the ListBox control functionality to be able to set the same view model source property that the ListBox control sets for you when you select a new item. This functionality belongs to the view or the control.

这篇关于WPF MVVM轻绑定到同一对象的多个ListBoxItem的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆