【问题标题】:Adding a RadioButton to a WPF ListItem in XAML using a ControlTemplate使用 ControlTemplate 将 RadioButton 添加到 XAML 中的 WPF ListItem
【发布时间】:2013-04-10 20:15:20
【问题描述】:

gehho's answer to "MVVM Group Radio Button" 之后,我正在尝试将单选按钮添加到列表项中,以便在选择列表项时选中单选按钮,而在未选中列表项时取消选中单选按钮。 Kelly 对他或她的“将 RadioButton IsChecked 绑定到 ListBoxItem IsSelected 和 ListBox IsFocused”问题有a great answer,看起来它应该满足我的需要。但是,我对 Kelly 的 XAML 的简单转换不起作用 - 单选按钮仍未选中。这是我的 MainWindow.xaml 的全部内容

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:SampleData="clr-namespace:Expression.Blend.SampleData.SampleDataSource" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    x:Class="RadioButton.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="640" Height="480">

    <Window.Resources>
        <SampleData:SampleDataSource x:Key="SampleDataSource" d:IsDataSource="True"/>
        <ControlTemplate x:Key="LBItemControlTemplate" TargetType="{x:Type ListBoxItem}">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="20"/>
                    <ColumnDefinition Width="*"/>
                </Grid.ColumnDefinitions>
                <TextBlock TextWrapping="Wrap" Text="{Binding Property1}" Grid.Column="1"/>
                <RadioButton x:Name="rbIsSelected" IsChecked="False" IsEnabled="False"/>
            </Grid>
            <ControlTemplate.Triggers>
                <MultiTrigger>
                    <MultiTrigger.Conditions>
                        <Condition Property="IsSelected" Value="True"/>
                        <Condition Property="Selector.IsSelectionActive" Value="True"/>
                    </MultiTrigger.Conditions>
                    <Setter Property="IsChecked" TargetName="rbIsSelected" Value="True"/>
                </MultiTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
        <DataTemplate x:Key="ListBoxItemTemplate">
            <ListBoxItem Template="{StaticResource LBItemControlTemplate}"/>
        </DataTemplate>
    </Window.Resources>

    <Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource SampleDataSource}}">
        <ListBox ItemsSource="{Binding Collection}" ItemTemplate="{DynamicResource ListBoxItemTemplate}" SelectionMode="Single"/>
    </Grid>
</Window>

任何人都可以看到为什么这不起作用并建议修复或不​​同的方法吗?

【问题讨论】:

    标签: wpf xaml listview radio-button controltemplate


    【解决方案1】:

    你知道ItemsControls 会自动为找到的每个数据项创建一个容器项吗?您的 DataTemplate 包含一个永远不会正确的 ListBoxItem。你基本上说“当你在 ListBoxItem 中显示我的内容时,创建一个新的 ListBoxItem”。所以你的代码依赖于你分离的ListBoxItem,它永远不能被选中,因为它不是ItemsControl中的容器项,因此它不能工作。您的DataTemplate 只是容器内的内容,在这种情况下,DataTemplate 应该定义您的数据在ListBoxItem 中的外观。

    这是一个小但不一定是好的实践示例,但它表明您不必创建ListBoxItem,它会自动存在:

    作为资源的某处,例如 Window.Resources 或 app.xaml:

    <DataTemplate x:Key="myTemplate">
        <StackPanel Orientation="Horizontal">
            <CheckBox IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}, Path=IsSelected}"/>
            <TextBlock Text="{Binding}"/>
        </StackPanel>
    </DataTemplate>
    

    以及使用本身

    <ListBox x:Name="test" ItemTemplate="{StaticResource myTemplate}"/>
    

    这种情况下的列表框需要在后面的代码中设置一个 ItemsSource。

    【讨论】:

    • 完美 - 这是我完全忘记的 RelativeSource/FindAncestor/AncestorType 的东西。这正是我想要的,并且可以根据需要使用RadioButton 而不是Checkbox。也感谢您提供信息丰富的温和解释。
    猜你喜欢
    • 2017-04-05
    • 2010-10-01
    • 2023-01-16
    • 2019-06-17
    • 1970-01-01
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多