简体   繁体   English

ListBox中的ComboBox不会触发SelectionChanged事件

[英]ComboBox in a ListBox does not fire SelectionChanged event

I have a wpf, mvvm app, using the catel (http://catel.codeplex.com) framework\\toolkit, C# .Net 4.0. 我有一个wpf,mvvm应用程序,使用catel(http://catel.codeplex.com)framework \\ toolkit,C#.Net 4.0。 The app has a ListBox with a TextBlock and ComboBox. 该应用程序具有带TextBlock和ComboBox的ListBox。 The ListBox and ComboBox are populated from 2 different ObservableCollection from the ViewModel. ListBox和ComboBox由ViewModel的2个不同的ObservableCollection填充。 I need to save (to a db), when the user clicks a button, each row in the ListBox where the user has selected an item from the ComboBox. 当用户单击按钮时,我需要保存(到数据库),ListBox中用户从ComboBox中选择项目的每一行。 The SelectionChanged event does not fire for any of the ComboBoxes in the ListBox. SelectionBox函数中的任何ComboBox都不会触发SelectionChanged事件。 The idea being that I add to a list (ArrayList or IList?), in the ViewModel, each time the user selects an item in a ComboBox and for what row the item has been selected. 我想在每次用户选择ComboBox中的项目以及选择项目的哪一行时,在ViewModel中添加到列表(ArrayList或IList?)。

Or am I going about this the wrong way by trying to use the ComboBoxe SelectionChanged event? 还是通过尝试使用ComboBoxe SelectionChanged事件来以错误的方式进行处理? I also tried iterating thru the ListBox.Items but this seems like a hak and I want to avoid ui element logic in the ViewModel if possible. 我也尝试通过ListBox.Items迭代,但这似乎是一个hak,我想在可能的情况下避免ViewModel中的ui元素逻辑。

The xaml: xaml:

<Grid>
<StackPanel Orientation="Horizontal">
    <Label Width="180">Field1</Label>
    <ListBox Height="200" 
            IsSynchronizedWithCurrentItem="True" 
            ItemsSource="{Binding List1, Mode=OneWay}" 
            Name="listBox1" 
            SelectionMode="Single" 
            Width="300">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Width="290">
                    <TextBlock Width="90" Text="{Binding}"></TextBlock>
                        <ComboBox Width="180" ItemsSource="{Binding DataContext.List2, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" DisplayMemberPath="Field1">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="SelectionChanged">
                                    <catel:EventToCommand Command="{Binding SelectionChangedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}" DisableAssociatedObjectOnCannotExecute="False" PassEventArgsToCommand="True" />
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </ComboBox>
                    </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</StackPanel>

ViewModel code: ViewModel代码:

//in the ViewModel constructor

SelectionChangedCommand = new Command<SelectionChangedEventArgs>(OnSelectionChangedCommandExecute, OnSelectionChangedCommandCanExecute);



public Command<SelectionChangedEventArgs> SelectionChangedCommand { get; private set; }

private bool OnSelectionChangedCommandCanExecute()
{
    return true;
}

private void OnSelectionChangedCommandExecute(SelectionChangedEventArgs e)
{
    // add or update list....
}

In Command binding you have used binding which has relative source binding... 在Command绑定中,您使用了具有相对源绑定的绑定...

consider making these changes in binding 考虑在绑定中进行这些更改

1) using list box as Ancestortype 1)使用列表框作为Ancestortype

2) While binding use Path=DataContext.SelectionChangedCommand otherwise it will take list box as datacontext. 2)绑定时使用Path = DataContext.SelectionChangedCommand,否则它将把列表框作为datacontext。

<catel:EventToCommand Command="{Binding Path=DataContext.SelectionChangedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" DisableAssociatedObjectOnCannotExecute="False" PassEventArgsToCommand="True" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM