Wpf Expander Collection, как сделать так, чтобы родительская модель ViewModel знала, какой объект Expander текущий?

В представлении, которое содержит элемент, имеющий коллекцию дочерних элементов, у меня есть ItemsControl, в котором размещается коллекция дочерних элементов. Отдельные элементы содержатся в расширителе. Когда дочерний элемент расширяется, мне нужно, чтобы родительская модель представления знала, над каким дочерним элементом действуют соответствующие действия. Мне удалось реализовать триггер события, который передает дочерний объект в качестве параметра родительской модели представления, а затем модель родительского представления может установить свойство SelectedChildObject. Это то, что мне нужно, но где этого не хватает, так это когда несколько элементов расширяются, и пользователь действует с элементом, которого нет в самом последнем развернутом элементе. Когда это происходит, элемент, с которым они взаимодействуют, не соответствует свойству SelectedChildObject, поскольку только последний развернутый объект будет значением свойства.

Я видел решения, которые используют ListBox для размещения Expander, а затем устанавливают Expander IsExpanded на основе ListBox IsSelected, но мне не нравится это решение, потому что оно позволяет открывать только один расширитель за раз, плюс это не похоже Возможно, что 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>

person Mike .    schedule 09.04.2014    source источник


Ответы (1)


Какие действия вы пытаетесь выполнить на слотах?

Что-то вроде удаления последнего обработанного слота? В таком случае вам, вероятно, придется написать поведение или элемент управления, который будет захватывать события PreviewMouseDown и отправлять команду / событие для уведомления вашей родительской модели представления. Но это не идеально.

И в любом случае вы, вероятно, захотите, чтобы «Выбранный слот» был выделен, прежде чем его можно будет удалить. Вы также можете попробовать удалить фон расширителя и использовать ListBox. Таким образом, когда вы нажимаете на фон своего слота, он выбирает и выделяет ListBoxItem. Таким образом вы можете привязать SelectedItem к виртуальной машине.

person Dmitry    schedule 09.04.2014