2013-11-13 3 views
1

Рассмотрим приведенное ниже упрощенное приложение, которое позволяет выбирать между двумя элементами, каждый из которых имеет логические свойства A и B, привязанные к переключателям. Идея состоит в том, что вы должны иметь возможность устанавливать A/B независимо для каждого элемента, и если вы переключаетесь между элементами, радиокнопки должны отражать флаги для этого элемента. Однако это не так.RadioButton TwoWay Binding Issues

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)); 
     } 
    } 
} 

окно XAML (не код позади):

<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. Что-то неуловимое происходит, когда свойство SelectedElement изменяется на ContentPresenter, которое каким-то образом запускает привязку TwoWay, я думаю, заставляя ее перезаписывать значения свойств, но я не могу понять, почему это произойдет или как ее решить. Это преднамеренно упрощенная версия того, что я вижу в более крупном приложении.

Любая идея, что здесь происходит?

ответ

2

Поскольку они принадлежат к одной группе, см. GroupName Property, вы можете установить отдельное имя GroupName для каждого элемента (каждый элемент имеет другую группу).

+0

Это устраняет проблему, если я явно очистил другой флаг в моем обработчике для средства настройки свойств. Это немного неудобно; поведение по умолчанию сгруппированных радиокнопок, очищающих другие связанные флаги, выглядит любезно. В данном конкретном случае у него просто странное поведение (очистка каким-то образом применяется к устаревшей версии привязки, у которой еще нет сброса контекста данных)? –

+0

Да, это немного неудобно, это больше делает сцену, использующую пользовательский элемент управления наследует togglebutton и перезаписывает свой стиль (выглядит как радиобуй, но не имеет групповой способности) –

Смежные вопросы