首页 > 解决方案 > 将(TwoWay)字符串绑定到两个带有内容的单选按钮

问题描述

我想将(TwoWay)一个字符串值(“True”或“False”)绑定到内容为“True”和“False”的两个单选按钮。

条件

  1. 使用 select "True" RadioButton 时,字符串值应为 "True",反之亦然,用于 "False" 单选按钮。
  2. 一次只有一个 RadioButton 可以选择 True 或 False。
  3. 有字符串列表,单选按钮是 DataTemplate 的一部分。

XAML

<Grid.RowDefinitions>
    <RowDefinition Height="*"/>
    <RowDefinition Height="Auto"/>
</Grid.RowDefinitions>

<ListBox ItemsSource="{Binding Values}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <RadioButton x:Name="rbTrue" Content="True" IsChecked="{Binding Value,Mode=TwoWay}" />
                <RadioButton x:Name="rbFalse" Content="False" IsChecked="{Binding Value,Mode=TwoWay}"/>
            </StackPanel>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=Value,Mode=TwoWay}" Value="True">
                <Setter Property="IsChecked" TargetName="rbTrue" Value="True"/>
                <Setter Property="IsChecked" TargetName="rbFalse" Value="False"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=Value,Mode=TwoWay}" Value="False">
                <Setter Property="IsChecked" TargetName="rbTrue" Value="False"/>
                <Setter Property="IsChecked" TargetName="rbFalse" Value="True"/>
            </DataTrigger>
        </DataTemplate.Triggers>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

XAML.CS

public partial class MainWindow : Window
{
    MainViewModel viewModel;

    public MainWindow()
    {
        InitializeComponent();

        viewModel = new MainViewModel();

        this.DataContext = viewModel;
    }
}

视图模型

public class MainViewModel : ModelBase
{
    private List<MainModel> values;
    public List<MainModel> Values
    {
        get
        {
            return values;
        }
        set
        {
            if (value != values)
            {
                values = value;
                OnPropertyChanged("Values");
            }
        }
    }

    public MainViewModel()
    {
        Values = new List<MainModel>();

        for (int i = 0; i < 10; i++)
        {
            if (i % 2 == 0)
                Values.Add(new MainModel() { Value = true });
            else
                Values.Add(new MainModel() { Value = false });
        }
    }
}

模型

public class MainModel : ModelBase
{
    private bool strValue;
    public bool Value
    {
        get
        {
            return strValue;
        }
        set
        {
            if (value != strValue)
            {
                strValue = value;
                OnPropertyChanged("Value");
            }
        }
    }
}

模型库

public abstract class ModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }
}

用户界面

在此处输入图像描述

我几乎尝试了我所知道的一切,还检查了不同论坛和其他材料上的大多数在线相关链接。

我想要的只是基于列表中用户选择的值“真”或“假”。

提前致谢。

标签: c#wpfxamldata-bindingtwo-way-binding

解决方案


我假设您的意思是“将(TwoWay)布尔值绑定到两个单选按钮”而不是“将(TwoWay)字符串绑定到两个单选按钮”,因为Value具有数据类型bool

首先,不要使用DataTriggers; 删除它们。

相反,在“false”按钮的绑定上,添加一个否定布尔值的转换器:

<RadioButton x:Name="rbFalse" Content="False" IsChecked="{Binding Value,Mode=TwoWay,Converter={StaticResource NegateConverter}}"/>

在您的 XAML 资源中,您需要定义转换器:

<local:NegateConverter x:Key="NegateConverter"/>

替换local为您在其中定义类的任何命名空间NegateConverter

这是转换器的代码:

/// <summary>
/// This converter negates a boolean value.
/// </summary>
[ValueConversion(typeof(bool), typeof(bool))]
public class NegateConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool bValue = false;
        if (value is bool)
        {
            bValue = (bool)value;
        }
        return !bValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool bValue = false;
        if (value is bool)
        {
            bValue = (bool)value;
        }
        return !bValue;
    }
}

推荐阅读