Группировка RadioButton не работает в WPF при использовании ItemControl и DataBinding

У меня проблемы с группировкой RadioButtons при использовании формы WPF и DataBinding.

Если я вручную создаю свои элементы управления, поведение будет таким, как ожидалось, и пользователю разрешено выбрать только один элемент из группы радиокнопок (нижний GroupBox), но если я использую вложенные элементы управления ItemControl для создания макета и использую группировку привязки данных, не работает должным образом и пользователю разрешено выбирать несколько радиокнопок в одной группе (верхний groupBox), как видно на этом связанном снимке экрана 1.

Я попытался привязать свойство GroupName, но не смог найти свойство привязки для использования для свойства GroupName. Возможно, свойство Text TextBlock в той же строке сетки можно использовать, но мне не удалось найти правильный синтаксис Binding для ссылки на него.

Как можно заставить работать группировку?

Вот XAML:

<Window x:Class="RadioButtonMadness.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" Title="MainWindow" SizeToContent="WidthAndHeight">

    <Window.Resources>
        <Style TargetType="RadioButton">
            <Setter Property="Margin" Value="10" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="Height" Value="22" />
        </Style>
        <Style TargetType="TextBlock">
            <Setter Property="Margin" Value="10" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="Height" Value="22" />
        </Style>
    </Window.Resources>

    <Grid>
        <Grid.ColumnDefinitions />
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <GroupBox Header="Prognostic factors - NOK">
            <ItemsControl ItemsSource="{Binding PrognosticFactors}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Name="PrognosticFactors" Grid.Row="0" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="1*"/>
                                <ColumnDefinition Width="2*"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions />
                            <TextBlock Text="{Binding Title}" />
                            <ItemsControl ItemsSource="{Binding Options}" Grid.Column="1">
                                <ItemsControl.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Orientation="Horizontal" />
                                    </ItemsPanelTemplate>
                                </ItemsControl.ItemsPanel>
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <RadioButton Content="{Binding Key}" />
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </Grid>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </GroupBox>
        <GroupBox Header="Prognostic factors - OK" Grid.Row="1">
            <StackPanel>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="2*"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions/>
                    <TextBlock Text="Test4" Grid.Column="0"/>
                    <StackPanel Orientation="Horizontal" Grid.Column="1">
                        <RadioButton Content="One"/>
                        <RadioButton Content="Two"/>
                        <RadioButton Content="Three"/>
                    </StackPanel>
                </Grid>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="1*"/>
                        <ColumnDefinition Width="2*"/>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions />
                    <TextBlock Text="Test5" Grid.Column="0"/>
                    <StackPanel Orientation="Horizontal" Grid.Column="1">
                        <RadioButton Content="One"/>
                        <RadioButton Content="Two"/>
                        <RadioButton Content="Three"/>
                    </StackPanel>
                </Grid>
            </StackPanel>
        </GroupBox>
    </Grid>
</Window>

А также код:

using System;
using System.Collections.Generic;
using System.Windows;

namespace RadioButtonMadness
{
    public class Option
    {
        public String Key{ get; set; }
        public Double Value { get; set; }

        public Option(String key, Double value)
        {
            Key = key;
            Value = value;
        }
    }

    public class PrognosticFactor
    {
        private String title;
        public List<Option> Options
        {
            get
            {
                var list = new List<Option>();
                list.Add(new Option("One", 1));
                list.Add(new Option("Two", 2));
                list.Add(new Option("Three", 3));
                return list;
            }
        }

        public String Title
        {
            get { return title; }
        }

        public PrognosticFactor(String value)
        {
            title = value;
        }
    }

    public class ViewModel
    {
        public List<PrognosticFactor> PrognosticFactors
        {
            get
            {
                var list = new List<PrognosticFactor>();
                list.Add(new PrognosticFactor("Test1"));
                list.Add(new PrognosticFactor("Test2"));
                list.Add(new PrognosticFactor("Test3"));
                return list;
            }
        }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new ViewModel();
        }
    }
}

person Jonathan    schedule 25.01.2018    source источник


Ответы (1)


Просто привяжите GroupName к свойству Title. Сделать это можно примерно так:

<ItemsControl.ItemTemplate>
    <DataTemplate>
        <RadioButton Content="{Binding Key}" GroupName="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}, Path=DataContext.Title}" />
    </DataTemplate>
</ItemsControl.ItemTemplate>
person Andrew Shkolik    schedule 25.01.2018
comment
Превосходно! Пятно на. Я пробовал привязаться к ItemsControl вместо Grid. Дух! - person Jonathan; 25.01.2018