从DataTemplate上的按钮获取ListBox行对象

时间:2010-01-23 23:51:13

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

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

OnClick中如何从Buttonobject 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>

4 个答案:

答案 0 :(得分:2)

您可以选择使用Command而不是Event。如果将按钮绑定到命令并将命令参数传递给它,则应该能够获取与该按钮相关的项。示例代码:

<!-- 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命令。

祝你好运。

答案 1 :(得分:1)

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

How can I find WPF controls by name or type?

所以,例如,你可以通过这样的调用从click事件中找到ListBoxItem:

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

答案 2 :(得分:0)

你试过ListBox.SelectedItem吗?

答案 3 :(得分:0)

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

可以在listview本身找到itemcontainergenerator作为属性。 (从技术上讲,物品控制,因为它定义的地方)