Wpf Expander Collection,如何让父ViewModel知道哪个Expander对象是当前的?

时间:2014-04-09 15:46:13

标签: wpf mvvm expander

在包含具有子项集合的项目的视图中,我有一个ItemsControl,它承载子项集合。各个项目包含在Expander中。扩展子项时,我需要父视图模型才能知道正在对哪个子项进行操作。我能够实现一个事件触发器,它将子对象作为参数传递给父视图模型,然后父视图模型可以设置SelectedChildObject属性。这就是我需要的东西,但是它不足之处是当多个项目被扩展时,用户对不在最近扩展的项目中的项目进行操作。发生这种情况时,他们正在与之交互的项目与SelectedChildObject属性不匹配,因为只有最近扩展的对象才是属性值。

我已经看到使用ListBox来包含Expander的解决方案,然后根据ListBox IsSelected设置Expander IsExpanded,但是我不喜欢这个解决方案,因为它只允许一次打开一个扩展器,加上它似乎不可能让Expander拉伸来填充ListBox中的所有空间,这看起来不太好。

有没有办法可以让父视图模型知道正在对哪个子对象进行操作?

<ItemsControl Grid.Row="0" Grid.Column="0"
                          ItemsSource="{Binding Slots, Mode=TwoWay}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Expander Padding="10">
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Expanded">
                        <i:InvokeCommandAction Command="{Binding DataContext.ExpandedCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" CommandParameter="{Binding}" />
                    </i:EventTrigger>
                </i:Interaction.Triggers>
                <Expander.Header>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="32" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>
                        <Image Grid.Row="0" Grid.Column="0"
                                           Height="16" Width="16" Source="/WpfApp1;component/Assets/Images/Warning.ico" />
                        <StackPanel Grid.Row="0" Grid.Column="1"
                                                Orientation="Horizontal">
                            <Label Content="Slot: " />
                            <Label Content="{Binding SlotNumber, Mode=TwoWay, ValidatesOnNotifyDataErrors=False}" />
                        </StackPanel>
                    </Grid>
                </Expander.Header>
                <StackPanel Margin="20">
                    <StackPanel Orientation="Horizontal">
                        <Label Content="Slot Number:" Margin="0 5 2 0" Width="100" />
                        <TextBox Text="{Binding SlotNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, ValidatesOnNotifyDataErrors=True, NotifyOnValidationError=True}" 
                                 Style="{DynamicResource Configuration.Input.TextBox}"
                                 Width="30" />
                    </StackPanel>

                    <StackPanel Orientation="Horizontal">
                        <Label Content="Modules:" Margin="0 5 2 0" Width="100" />
                        <ListBox ItemsSource="{Binding Source={x:Static local:SlotsViewModel.AllowedModules}}">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <CheckBox Content="{Binding}" 
                                              Command="{Binding DataContext.AddRemoveAllowedModuleCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" 
                                              CommandParameter="{Binding}"/>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                    </StackPanel>
                </StackPanel>
            </Expander>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

1 个答案:

答案 0 :(得分:0)

您尝试在老虎机上执行哪些操作?

删除最后一个操纵插槽的东西?如果是这样,那么您可能必须编写一个行为或控件来捕获PreviewMouseDown事件并发送命令/事件以通知您的父视图模型。但这并不理想。

无论如何,您可能希望突出显示“Selected slot”,因为它可以删除。您还可以尝试删除扩展器的背景并使用ListBox。因此,当您单击Slot的背景时,它会选择并突出显示ListBoxItem。通过这种方式,您可以将SelectedItem绑定到VM。