Получение ListBoxItem из события элемента управления шаблона элемента - PullRequest
1 голос
/ 11 августа 2011

В приведенном ниже коде WPF XAML, если я нахожусь в событии SelectTaskItemClick для шаблонной кнопки, как я могу получить объект ListBoxItem ItemSource, который в данный момент выбран?

    <!-- ListBox ITEMS -->
    <TaskDash:ListBoxWithAddRemove x:Name="listBoxItems" Grid.Row="1" Grid.Column="3" Grid.RowSpan="3"
        ItemsSource="{Binding}">
        <!--ItemsSource="{Binding}" DisplayMemberPath="Description">-->
        <Style TargetType="ListBoxItem">
            <Setter Property="IsSelected" Value="{Binding Path=Selected}"/>
        </Style>
        <TaskDash:ListBoxWithAddRemove.ItemTemplate>
            <DataTemplate>
                <DockPanel>
                    <Button DockPanel.Dock="Left" Click="SelectTaskItemClick">SELECT</Button>
                    <TextBox DockPanel.Dock="Left" Name="EditableDescription" Text="{Binding Description}" Height="25" Width="100" />
                    <Button DockPanel.Dock="Left" Click="EditTaskItemClick">EDIT</Button>
                </DockPanel>
            </DataTemplate>
        </TaskDash:ListBoxWithAddRemove.ItemTemplate>
    </TaskDash:ListBoxWithAddRemove>

Если я пытаюсь получить Parent или TemplateParent, он дает мне ContentPresenter или Style или что-то подобное.

    private void SelectTaskItemClick(object sender, RoutedEventArgs e)
    {
        Button taskItemButton = (Button) e.OriginalSource;
        ContentPresenter taskItem = (ContentPresenter) taskItemButton.TemplatedParent;
        taskItem = (ContentPresenter)taskItemButton.TemplatedParent;
        Style taskItem2 = taskItem.TemplatedParent;
        taskItem2 = taskItem.TemplatedParent;
        DependencyObject taskItem3 = taskItem2.Parent;
        //DependencyObject taskItem3 = taskItem2.TemplatedParent;
        //TaskItem taskItemObj = taskItem2;
    }

В приведенном выше коде я предполагаю, что он получает это из App.XAML, где определен этот пользовательский элемент управления ListBoxWithAddRemove.Как мне вместо этого перейти на XAML фактической формы [первый код, показанный выше]?

<Style x:Key="{x:Type TaskDash:ListBoxWithAddRemove}" TargetType="{x:Type     TaskDash:ListBoxWithAddRemove}">
            <Setter Property="Margin" Value="3" />
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="OverridesDefaultStyle" Value="True"/>
            <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            <Setter Property="MinWidth" Value="120"/>
            <Setter Property="MinHeight" Value="20"/>
            <Setter Property="AllowDrop" Value="true"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TaskDash:ListBoxWithAddRemove}">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="25" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>

                            <Button Grid.Column="0" Grid.Row="0" 
                                    Click="DeleteControlClick">Delete</Button>
                            <Button Grid.Column="1" Grid.Row="0" 
                                    Click="AddControlClick">Add</Button>
                            <Border 
                                Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2"
                                  Name="Border" 
                                  Background="{StaticResource WindowBackgroundBrush}"
                                  BorderBrush="{StaticResource SolidBorderBrush}"
                                  BorderThickness="1"
                                  CornerRadius="2">
                                <ScrollViewer 
                                    Margin="0"
                                    Focusable="false">
                                    <StackPanel Margin="0" IsItemsHost="True" />
                                </ScrollViewer>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

Ответы [ 2 ]

2 голосов
/ 11 августа 2011

Вы можете использовать VisualTreeHelper, чтобы пройти по дереву и остановиться, если у вас есть объект правильного типа, например,

private void SelectTaskItemClick(object sender, RoutedEventArgs e)
{
    var b = sender as Button;
    DependencyObject item = b;
    while (item is ListBoxItem == false)
    {
        item = VisualTreeHelper.GetParent(item);
    }
    var lbi = (ListBoxItem)item;
    //...
}

( Если вы просто хотите выбрать элемент, который можно (и нужно) просто выполнить через установленную привязку, например )

private void SelectTaskItemClick(object sender, RoutedEventArgs e)
{
    // The DataContext should be an item of your class that should
    // have a Selected property as you bind to it in a style.
    var data = (sender as FrameworkElement).DataContext as MyClass;
    data.Selected = true;
}
0 голосов
/ 11 августа 2011

Предполагая, что

<Style TargetType="ListBoxItem">
    <Setter Property="IsSelected" Value="{Binding Path=Selected}"/>
</Style>

работает так, как вам показалось, вы должны иметь возможность циклически просматривать элементы в вашем DataContext, используемом в качестве ItemsSource для вашего списка, и проверять свойство Selected каждого длянайти тот, который выбран в данный момент.Более типичным способом определения выбранного элемента из ListBox является использование listBox.SelectedItem, где listBox - это переменная, которая ссылается на рассматриваемый ListBox.В качестве альтернативы вы можете получить доступ к нему из параметра sender к методу SelectTaskItemClick.Другой метод, который вы можете попробовать, - это вспомогательные методы для обхода визуального дерева, например, описанные в Блок кодирования и Проект кода - LINQ to Visual Tree .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...