仅在外部事件上更改ToggleButton/RadioButton状态

3

我想介绍几个ToggleButton/RadioButton元素,它们具有以下特点:

  1. 映射到一个枚举,意味着DataContext有一个"public Mode CurrentMode"属性。
  2. 是互斥的(只有一个按钮被选中)
  3. 当单击按钮时,状态不会立即更改。相反,将发送请求到服务器。当响应到达时,状态才会更改。
  4. 对于选中/取消选中状态,具有不同的图像

例如,4个按钮将显示以下视图模型:

public class ViewModel
{
    public enum Mode { Idle, Active, Disabled, Running }
    Mode m_currentMode = Mode.Idle;

    public Mode CurrentMode
    {
        get { return m_currentMode; }
        set
        {
            SendRequest(value);
        }
    }

    // Called externally after SendRequest, not from UI
    public void ModeChanged(Mode mode)
    {
        m_currentMode = mode;
        NotifyPropertyChanged("CurrentMode");
    }
}

我的初始方法是使用如何将RadioButton绑定到枚举?问题中的解决方案,但这并不够,因为即使我在setter中不调用NotifyPropertyChanged,按钮状态也会立即更改。此外,我不喜欢“GroupName”hack。

有任何想法吗?我不介意创建一个自定义按钮类,因为我需要多个视图中的很多按钮。

我正在使用.NET 3.5 SP1和VS2008。

1个回答

0
如果你想使用单选按钮,你只需要进行一些小的调整以解决 RadioButton 的默认行为问题。
首先,你需要解决的问题是单选按钮的自动分组,根据它们共同的直接父容器进行分组。由于你不喜欢 "GroupName" 的 hack,你的另一个选择是将每个 RadioButton 放在其自己的网格或其他容器中。这将使每个按钮成为其自己组的成员,并强制它们基于它们的 IsChecked 绑定进行操作。
    <StackPanel Orientation="Horizontal">
        <Grid>
            <RadioButton IsChecked="{Binding Path=CurrentMode, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Idle}">Idle</RadioButton>
        </Grid>
        <Grid>
            <RadioButton IsChecked="{Binding Path=CurrentMode, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Active}">Active</RadioButton>
        </Grid>
        <Grid>
            <RadioButton IsChecked="{Binding Path=CurrentMode, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Disabled}">Disabled</RadioButton>
        </Grid>
        <Grid>
            <RadioButton IsChecked="{Binding Path=CurrentMode, Converter={StaticResource enumBooleanConverter}, ConverterParameter=Running}">Running</RadioButton>
        </Grid>
    </StackPanel>

这使我想到了下一个解决方法,即确保在单击按钮后它不会停留在其选中状态,因为需要触发设置调用,因为您正在绑定IsChecked属性。 您将需要发送额外的NotifyPropertyChanged,但它必须被推送到Dispatch线程的队列中,以便按钮将接收通知并更新其视觉IsChecked绑定。 将此添加到您的ViewModel类中,它可能替换您现有的NotifyPropertyChanged实现,并且我假设您的类实现了在问题代码中缺少的INotifyPropertyChanged:
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            Dispatcher uiDispatcher = Application.Current != null ? Application.Current.Dispatcher : null;
            if (uiDispatcher != null)
            {
                uiDispatcher.BeginInvoke(DispatcherPriority.DataBind,
                    (ThreadStart)delegate()
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                    });
            }
        }
    }

然后在您的CurrentMode的Setter中调用NotifyPropertyChanged(“CurrentMode”)。 您可能已经需要了这样的东西,因为您的Server的ModeChanged呼叫可能会在不是Dispatcher线程的线程上进行。

最后,如果您想要RadioButton有不同的Checked / Unchecked外观,则需要为它们应用样式。 快速搜索WPF RadioButton ControlTemplate最终找到了这个网站:http://madprops.org/blog/wpf-killed-the-radiobutton-star/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接