【问题标题】:Get the ListBox row object from a button that is on the DataTemplate从 DataTemplate 上的按钮获取 ListBox 行对象
【发布时间】:2010-01-23 23:51:12
【问题描述】:

我有一个ListBox 和一个DataTemplate。该模板上有一个Button。当点击 Button 时,我想对每一行的对象(在本例中为名为 WorkItemTypeMappings 的对象)执行一些逻辑。

OnClick 中,如何从Button (object sender) 转到按钮所在行的对象?

这是我的ListBox 的 XAML:

<ListBox ItemsSource="{Binding Source={StaticResource WorkItemTypeMappingsCollectionView}}" HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Name="lstWITypes">
    <ListBox.GroupStyle>
        <x:Static Member="GroupStyle.Default"/>
    </ListBox.GroupStyle>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid HorizontalAlignment="Stretch">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="2*"/>
                    <ColumnDefinition Width="2*"/>
                    <ColumnDefinition Width="50"/>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="{Binding SourceType, Converter={StaticResource WorkItemTypeToStringConverter}}"/>
                <ComboBox Grid.Column="1" SelectedItem="{Binding DestType}" ItemsSource="{Binding WorkItemTypesForCurrentDestProject, Source={x:Static loc:MainMediator.Instance}, diagnostics:PresentationTraceSources.TraceLevel=High}" DisplayMemberPath="Name" />

                <!-- This is the button-->
                <Button Grid.Column="2" Content="{Binding PercentMapped}" 
                        Click="ManualMappingClick"/>
            </Grid>
        </DataTemplate>                                        
    </ListBox.ItemTemplate>
</ListBox>

【问题讨论】:

    标签: c# .net wpf listbox wpf-controls


    【解决方案1】:

    您可以做的替代方法是使用命令而不是事件。如果将按钮绑定到命令并传递命令参数,您应该能够获取与该按钮相关的项目。示例代码:

    <!-- This is the button-->
     <Button
         Grid.Column="2"
         Content="{Binding PercentMapped}" 
         Command="SolutionNamespace:CommandClass.ButtonClickedCommand"
         CommandParameter="{Binding}" />
    

    我不确定您对 WPF 命令的熟悉程度,但您会注意到 CommandParameter 绑定到没有路径名的上下文,也就是说它绑定到您需要的 WorkItemTypeMappings。

    命令示例代码:

    public static SimpleCommand ButtonClickedCommand { get; set; }
    
    static CommandClass()
    {
        ButtonClickedCommand = new SimpleCommand
                               {
                                   ExecuteDelegate =
                                   x=> ButtonClicked(x as WorkItemTypeMappings)
                               };
    }
    
    
    public static ButtonClicked(WorkItemTypeMappings mappings)
    {
        if(mappings != null) MessageBox.Show(mapping.PercentMapped)
    }
    

    您会注意到 ButtonClickedCommand 是静态的,这是必需的,因为按钮无法从其当前绑定上下文访问命令。

    SimpleCommand 只是 ICommand 的一个简化实现,如果你不确定可以谷歌一下。我希望这不是对您的问题的过度杀伤,但 WPF 命令不会出错。

    祝你好运。

    【讨论】:

    • 这里有好东西。我一直想尝试一下命令。这将是一个很好的尝试。如果成功我会尝试并接受。
    • 效果太棒了!而且我觉得我以“正确的方式”做到了。感谢您的出色回答。
    • 很高兴你能用我最小的代码 sn-ps 让它工作。不客气。
    【解决方案2】:

    尝试使用 VisualTreeHelper 找到按钮的父 ListBoxItem。可以在这里找到一些很好的通用辅助函数:

    How can I find WPF controls by name or type?

    因此,例如,您可以通过如下调用从 click 事件中找到 ListBoxItem:

    ListBoxItem item = UIHelper.FindVisualParent<ListBoxItem>(sender);
    

    【讨论】:

    • 我不需要 ListBoxItem。我需要它背后的数据。 (正如我在问题中所说:“每一行的对象(在这种情况下是一个名为 WorkItemTypeMappings 的对象)”
    • ListBoxItem 是“它背后的数据”。拥有 ListBoxItem 后,您应该可以像这样进行转换:WorkItemTypeMappings dataObject = item as WorkItemTypeMappings;
    【解决方案3】:

    你试过 ListBox.SelectedItem 吗?

    【讨论】:

    • 是的。但是,可以单击按钮而不选择项目(我检查过)
    【解决方案4】:

    此外,如果您已经引用了 ListBoxControl,并且您还有表示该行的数据项(我假设是这样,因为您有绑定,因此可以将其拖出按钮上的 DataContext),您可以要求ItemsContainerGenerator. ContainerFromItem 为您提供该行的实际 UIElement。

    itemcontainergenerator 可以作为列表视图本身的属性找到。 (从技术上讲是 itemscontrol,因为这是定义它的地方)

    【讨论】:

    • 我实际上正在寻找另一条路。我需要代表行的数据项。
    猜你喜欢
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多