【问题标题】:MVVM radiobuttonsMVVM 单选按钮
【发布时间】:2010-10-27 08:42:42
【问题描述】:

请有人帮忙。我有一个有趣的问题。我正在尝试实现一个 MVVM 应用程序,并且我想在我的视图中绑定到单选按钮。

这是我的看法:

<StackPanel Orientation="Horizontal" Grid.ColumnSpan="2"  >
    <RadioButton GroupName="1" IsChecked="{Binding Path=NoteGeneral, Mode=TwoWay}">General</RadioButton>
    <RadioButton GroupName="1" IsChecked="{Binding Path=NoteContact, Mode=TwoWay}" >Contact</RadioButton>
    <RadioButton GroupName="1" IsChecked="{Binding Path=NoteAddress, Mode=TwoWay}" >Address</RadioButton>
    <RadioButton GroupName="1" IsChecked="{Binding Path=NotePhone, Mode=TwoWay}" >Phone</RadioButton>
</StackPanel>

这是我的 ViewModel:

    bool _NoteGeneral;
    public bool NoteGeneral
    {
        get { return _NoteGeneral; }
        set
        {
            _NoteGeneral = value;
            OnPropertyChanged("NoteGeneral");
        }
    }

    bool _NoteContact;
    public bool NoteContact
    {
        get { return _NoteContact; }
        set
        {
            _NoteContact = value;
            OnPropertyChanged("NoteContact");
        }
    }

    bool _NoteAddress;
    public bool NoteAddress
    {
        get { return _NoteAddress; }
        set
        {
            _NoteAddress = value;
            OnPropertyChanged("NoteAddress");
        }
    }

    bool _NotePhone;
    public bool NotePhone
    {
        get { return _NotePhone; }
        set
        {
            _NotePhone = value;
            OnPropertyChanged("NotePhone");
        }
    }

问题是这样的,当我单击不同的单选按钮时,属性设置器只会在第一次被调用(当我通过调试运行时)。例如当我再次单击 NoteGeneral、NoteContact 和 NoteGeneral 时,只有前两次单击会更新我的视图模型。我想我的绑定可能有问题,或者我正在以完全错误的方式处理这个问题。

谁能帮忙?

我应该如何在我的视图模型中实现单选按钮选择?

.NET 4 及更高版本

当 .NET 4 发布时,Microsoft 解决了 RadioButton 绑定的这个问题。 RadioButtons 的绑定现在可以正常工作,而无需下面列出的任何解决方法。

【问题讨论】:

    标签: data-binding mvvm


    【解决方案1】:

    看看here

    我没有实施提供的解决方案,但它是有道理的。执行单击时,底层框架控件会破坏您的绑定。解决方案是覆盖执行此操作的方法并仅依赖绑定。

    【讨论】:

    • 另请参阅stackoverflow.com/questions/2284752/… 了解其他一些解决方案,尤其是涉及列表框的相当简单的解决方案。
    • 链接已失效,这就是为什么您不应发布链接作为答案。
    【解决方案2】:

    我已经在我的博客上为这个问题写了a simple tip

    在这种情况下,您应该将 View 和 ViewModel 编写如下:

    <StackPanel Orientation="Horizontal" Grid.ColumnSpan="2">
        <RadioButton IsChecked="{Binding IsGeneralNote}">General</RadioButton>
        <RadioButton IsChecked="{Binding IsContactNote}">Contact</RadioButton>
        <RadioButton IsChecked="{Binding IsAddressNote}">Address</RadioButton>
        <RadioButton IsChecked="{Binding IsPhoneNote}">Phone</RadioButton>
    </StackPanel>
    


    public enum Note
    {
        General,
        Contact,
        Address,
        Phone,
    }
    
    ...
    
        Note note = Note.General;
    
        public Note Note
        {
            get { return this.note; }
            set
            {
                if (this.note == value)
                    return;
    
                this.note = value;
                OnPropertyChanged("Note");
                OnPropertyChanged("IsGeneralNote");
                OnPropertyChanged("IsContactNote");
                OnPropertyChanged("IsAddressNote");
                OnPropertyChanged("IsPhoneNote");
            }
        }
    
        public bool IsGeneralNote
        {
            get { return Note == Note.General; }
            set { Note = value ? Note.General : Note; }
        }
    
        public bool IsContactNote
        {
            get { return Note == Note.Contact; }
            set { Note = value ? Note.Contact : Note; }
        }
    
        public bool IsAddressNote
        {
            get { return Note == Note.Address; }
            set { Note = value ? Note.Address : Note; }
        }
    
        public bool IsPhoneNote
        {
            get { return Note == Note.Phone; }
            set { Note = value ? Note.Phone : Note; }
        }
    ...
    

    【讨论】:

    • 这个解决方案不能解决 RadioButton 绑定在选择按钮时被破坏的问题,是吗?
    【解决方案3】:

    Jaime Rodriguez,在微软工作于 WPF,发布了一篇关于 WPF 的完整问答,最新一期有一篇关于 RadioButtons 和 MVVM 的帖子!

    帖子位于http://blogs.msdn.com/jaimer/archive/2009/09/22/wpf-discussion-090922.aspx,您想查看该帖子中的最后一项。我对解决方案进行了测试,结果令我满意。

    为方便起见引用:

    我已经在 .NET 3.5 SP1 中解决了这个问题。以下是我如何将一组单选按钮数据绑定到枚举值属性:

    <StackPanel>
        <RadioButton Content="New folder"
            IsChecked="{Binding Path=PublishTarget,
                        Converter={StaticResource equalityConverter},
                        ConverterParameter={x:Static local:PublishTarget.NewServerFolder}, Mode=TwoWay}"
            GroupName="1" />
    
        <RadioButton Content="Existing folder"
            IsChecked="{Binding Path=PublishTarget,
                        Converter={StaticResource equalityConverter},
                        ConverterParameter={x:Static local:PublishTarget.ExistingServerFolder},
                        Mode=TwoWay}"
            GroupName="2" />
    
        <RadioButton Content="Local folder"
            IsChecked="{Binding Path=PublishTarget,
                        Converter={StaticResource equalityConverter},
                        ConverterParameter={x:Static local:PublishTarget.LocalFolder},
                        Mode=TwoWay}"
            GroupName="3" />
    </StackPanel>
    

    将每个单选按钮的 GroupName 设置为唯一值可防止在用户单击单选按钮时绑定被破坏。这里我依靠数据源来实现 INotifyPropertyChanged,它将告诉其他单选按钮进行更新。类似的方法应该适用于 ItemsControl 中的单选按钮。

    【讨论】:

      【解决方案4】:

      您必须在 XAML 绑定中设置 UpdateSourceTrigger="PropertyChanged",例如:

      <StackPanel Grid.Column="1" Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
          <RadioButton Name="rdbTimeFormat12" GroupName="TimeFormat" Content="12 Hrs" IsChecked="{Binding Radio1IsCheck,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
          <RadioButton Name="rdbTimeFormat24" GroupName="TimeFormat" Margin="40,0,0,0" Content="24 Hrs" IsChecked="{Binding Radio2IsCheck,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
      </StackPanel>
      

      【讨论】:

        猜你喜欢
        • 2011-02-12
        • 1970-01-01
        • 1970-01-01
        • 2014-04-25
        • 2011-08-19
        • 2014-06-19
        • 2023-04-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多