单选按钮双向绑定问题 [英] RadioButton TwoWay Binding Issues

查看:73
本文介绍了单选按钮双向绑定问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下简化的应用程序,该应用程序允许您在两个元素之间进行选择,每个元素都具有绑定到单选按钮的A和B布尔属性。想法是您应该能够为每个元素独立设置A / B,并且如果在元素之间进行切换,则单选按钮应该反映该元素的标志。

Consider the below simplified application, which allows you to select between two elements, each of which has A and B boolean properties that are bound to radio buttons. The idea is that you should be able to set A/B independently for each element and if you switch between elements, the radio buttons should reflect the flags for that element. This isn't what happens however.

ViewModel:

ViewModel:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Documents;

namespace SandboxWpf
{
    public sealed class Element : INotifyPropertyChanged
    {
        private bool _memberA;

        public bool MemberA
        {
            get { return _memberA; }
            set
            {
                if (value != _memberA)
                {
                    _memberA = value;
                    OnPropertyChanged();                    
                }
            }
        }

        private bool _memberB;
        public bool MemberB
        {
            get { return _memberB; }
            set
            {
                if (value != _memberB)
                {
                    _memberB = value;
                    OnPropertyChanged();                    
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public sealed class MainViewModel : INotifyPropertyChanged
    {
        private readonly List<Element> _elements;

        public MainViewModel()
        {
            _elements = new List<Element>();
            _elements.Add(new Element());
            _elements.Add(new Element());
        }

        public IEnumerable<Element> Elements
        {
            get { return _elements; }
        }

        private Element _selectedElement;

        public Element SelectedElement
        {
            get { return _selectedElement; }
            set
            {
                if (value != _selectedElement)
                {
                    _selectedElement = value;
                    OnPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Window XAML(后面没有代码):

Window XAML (no code behind):

<Window x:Class="SandboxWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:SandboxWpf="clr-namespace:SandboxWpf"
        Title="MainWindow" Height="350" Width="525">

    <Window.DataContext>
        <SandboxWpf:MainViewModel/>
    </Window.DataContext>

    <StackPanel Orientation="Horizontal">
        <ListBox ItemsSource="{Binding Elements}"
                 SelectedItem="{Binding SelectedElement, Mode=TwoWay}" />

        <ContentPresenter Content="{Binding SelectedElement}">
            <ContentPresenter.Resources>
                <DataTemplate DataType="{x:Type SandboxWpf:Element}">
                    <StackPanel Orientation="Horizontal">
                        <RadioButton Content="A" IsChecked="{Binding MemberA, Mode=TwoWay}"/>
                        <RadioButton Content="B" IsChecked="{Binding MemberB, Mode=TwoWay}"/>
                    </StackPanel>
                </DataTemplate>
            </ContentPresenter.Resources>
        </ContentPresenter>
    </StackPanel>
</Window>

您可以使用每个元素上的单选按钮切换A和B值。但是,如果将第一个元素和第二个元素设置为不同的值(一个A和一个B),然后返回到另一个选定的元素,则另一个元素现在将A和B都设置为false。当ContentPresenter上的SelectedElement属性发生更改时,某种奇怪的事情发生了,它以某种方式触发了我认为的TwoWay绑定,导致它覆盖了属性值,但我不知道为什么会发生这种情况或如何解决它。这是我在较大的应用程序中看到的特意简化的版本。

You can switch the A and B values using the radio buttons on each element. However, if you set the first element and second element to different values (one A and one B), then go back to the other selected element, the other element will now have both A and B set to false. Something wonky is happening when the SelectedElement property changes on the ContentPresenter that somehow triggers the TwoWay binding I think, causing it to overwrite the property values, but I can't figure out why this would happen or how to resolve it. This is a deliberately simplified version of something I'm seeing in a larger application.

你知道这里发生了什么吗?

Any idea what's happening here?

推荐答案

由于它们属于同一组,请参见 GroupName属性,您可以为每个Element(每个元素具有不同的组)设置单独的GroupName。

Because they belong to same Group, see GroupName Property, you can set individual GroupName for each Element(every element has different group).

<DataTemplate DataType="{x:Type SandboxWpf:Element}">
     <StackPanel Orientation="Horizontal">
          <RadioButton GroupName="{Binding ElementGroupName}" Content="A" IsChecked="{Binding MemberA, Mode=TwoWay}"/>
          <RadioButton GroupName="{Binding ElementGroupName}" Content="B" IsChecked="{Binding MemberB, Mode=TwoWay}"/>
      </StackPanel>
</DataTemplate>

这篇关于单选按钮双向绑定问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆