单选按钮的 WPF 转换器不起作用

发布于 2024-10-19 22:02:12 字数 2069 浏览 1 评论 0原文

我有两个绑定到同一属性的单选按钮。单选按钮有 2 个转换器。但第二个复选框的转换仅发生第一次。代码中是否有问题。

<RadioButton Margin="5,1" GroupName="groupValueOrTime" Name="radioButtonTimeDriven" VerticalAlignment="Top" IsChecked="{Binding Path=TriggerType ,Converter={StaticResource dailyTriggerConverter}}"  Grid.Column="0" Grid.Row="0" >Time Driven</RadioButton>
<RadioButton Margin="5,1" GroupName="groupValueOrTime" Name="radioButtonValueDriven" VerticalAlignment="Top" Grid.Column="0" Grid.Row="1" IsChecked="{Binding Path=TriggerType,Converter={StaticResource valueDrivenTriggerConverter}}" >Value Driven</RadioButton>

代码:

public class TriggerTypeDailyToBoolProperty:IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
       //convert from TriggerType to bool:
        int TriggerType=int.Parse(value.ToString());
        if (TriggerType == 0 || TriggerType == 1 || TriggerType == 2 || TriggerType == 3 || TriggerType == 4 || TriggerType == 5 || TriggerType == 6)
            return true;
        else
            return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool isChecked = (bool)value;
        return (isChecked? 0: -1);
    }

    #endregion
}

public class TriggerTypeValueDrivenToBoolProperty : IValueConverter
{
   #region IValueConverter Members

   public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   {
       //convert from TriggerType to bool:
       int TriggerType = int.Parse(value.ToString());
       if (TriggerType == 9)
           return true;
       else
           return false;
   }

   public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   {
       bool isChecked = (bool)value;
       return (isChecked ? 9 : -1);
   }

   #endregion
}

I have two radiobuttons which are bound to the same property .There are 2 converters for the radio buttons. But the conversion for the 2 nd checkbox only happens the 1st time . Is there something wrong in the code.

<RadioButton Margin="5,1" GroupName="groupValueOrTime" Name="radioButtonTimeDriven" VerticalAlignment="Top" IsChecked="{Binding Path=TriggerType ,Converter={StaticResource dailyTriggerConverter}}"  Grid.Column="0" Grid.Row="0" >Time Driven</RadioButton>
<RadioButton Margin="5,1" GroupName="groupValueOrTime" Name="radioButtonValueDriven" VerticalAlignment="Top" Grid.Column="0" Grid.Row="1" IsChecked="{Binding Path=TriggerType,Converter={StaticResource valueDrivenTriggerConverter}}" >Value Driven</RadioButton>

Code:

public class TriggerTypeDailyToBoolProperty:IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
       //convert from TriggerType to bool:
        int TriggerType=int.Parse(value.ToString());
        if (TriggerType == 0 || TriggerType == 1 || TriggerType == 2 || TriggerType == 3 || TriggerType == 4 || TriggerType == 5 || TriggerType == 6)
            return true;
        else
            return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool isChecked = (bool)value;
        return (isChecked? 0: -1);
    }

    #endregion
}

public class TriggerTypeValueDrivenToBoolProperty : IValueConverter
{
   #region IValueConverter Members

   public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   {
       //convert from TriggerType to bool:
       int TriggerType = int.Parse(value.ToString());
       if (TriggerType == 9)
           return true;
       else
           return false;
   }

   public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
   {
       bool isChecked = (bool)value;
       return (isChecked ? 9 : -1);
   }

   #endregion
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

软糖 2024-10-26 22:02:12

组合分组、单选按钮和绑定不起作用。绑定的一个奇怪功能是,如果您在代码中设置绑定目标属性的值,则会禁用绑定。绑定设计似乎做出的假设是,更改目标属性的唯一方法是使用 UI 或更改其绑定到的源属性,并且如果一段代码显式设置绑定的值目标属性,它知道它在做什么。

不幸的是,这意味着分组单选按钮(在更改时在代码中设置彼此的值)在用户单击它们时会破坏它们的绑定。哎呀。

解决方案很简单:将单选按钮绑定到视图模型中的属性,消除分组,并将逻辑放入视图模型中以处理绑定属性的互斥性质,例如:

private bool _Option1;

public bool Option1
{
   get { return _Option1; }
   set
   {
      if (value != _Option1)
      {
         _Option1 = value;
         if (value)
         {
            Option2 = false;
            Option3 = false;
         }
      }
      OnPropertyChanged("Option1");
   }
}

Combining grouping, radio buttons, and binding doesn't work. An odd feature of binding is that if you set the value of a bound target property in code, it disables the binding. The assumption that the design of binding appears to be making is that the only ways you should change a target property is by using the UI or by changing the source property it's bound to, and if a piece of code explicitly sets the value of a bound target property, it knows what it's doing.

Unfortunately, this means that grouped radio buttons, which set each others' values in code when they're changed, break their bindings when the user clicks on them. Oops.

The solution's simple: bind the radio buttons to properties in your view model, eliminate the grouping, and put logic in the view model to handle the mutually-exclusive nature of the bound properties, e.g.:

private bool _Option1;

public bool Option1
{
   get { return _Option1; }
   set
   {
      if (value != _Option1)
      {
         _Option1 = value;
         if (value)
         {
            Option2 = false;
            Option3 = false;
         }
      }
      OnPropertyChanged("Option1");
   }
}
自在安然 2024-10-26 22:02:12

我认为您的视图模型中需要有两个不同的布尔属性。

请参考下面描述视图模型的示例。

public class TriggerViewModel : INotifyPropertyChanged
{
    private bool _triggerTypeValue;
    private bool _triggerTypeTime;
    public bool TriggerTypeValue
    {
        get
        {
            return _triggerTypeValue;
        }
        set
        {
            _triggerTypeValue = value;
            OnPropertychanged("TriggerTypeValue");
            SetTriggerTypeTime(!_triggerTypeValue);
        }
    }

    public bool TriggerTypeTime
    {
        get
        {
            return _triggerTypeTime;
        }
        set
        {
            _triggerTypeTime = value;
            OnPropertychanged("TriggerTypeTime");
            SetTriggerTypeValue(!_triggerTypeTime);
        }
    }

    public TriggerViewModel()
    {
        _triggerTypeValue = false;
        _triggerTypeTime = true;
    }

    private void SetTriggerTypeTime(bool value)
    {
        _triggerTypeTime = value;
        OnPropertychanged("TriggerTypeTime");
    }

    private void SetTriggerTypeValue(bool value)
    {
        _triggerTypeValue = value;
        OnPropertychanged("TriggerTypeValue");
    }

    private void OnPropertychanged(string propertyName)
    {
        if(PropertyChanged!= null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

对于 XAML

<RadioButton Margin="5,1" GroupName="groupValueOrTime" Name="radioButtonTimeDriven" 
             VerticalAlignment="Top" IsChecked="{Binding Path=TriggerType}"  
             Grid.Column="0" Grid.Row="0">
     Time Driven 
</RadioButton>

<RadioButton Margin="5,1" GroupName="groupValueOrTime" Name="radioButtonValueDriven" 
             VerticalAlignment="Top" Grid.Column="0" Grid.Row="1" 
             IsChecked="{Binding Path=TriggerType}">
      Value Driven
<RadioButton>

注意:此方法删除了转换器,并允许您将业务逻辑保留在中央视图模型中。

I think you will require to have two different boolean properties in your view model.

Please refer below example depicting viewmodel.

public class TriggerViewModel : INotifyPropertyChanged
{
    private bool _triggerTypeValue;
    private bool _triggerTypeTime;
    public bool TriggerTypeValue
    {
        get
        {
            return _triggerTypeValue;
        }
        set
        {
            _triggerTypeValue = value;
            OnPropertychanged("TriggerTypeValue");
            SetTriggerTypeTime(!_triggerTypeValue);
        }
    }

    public bool TriggerTypeTime
    {
        get
        {
            return _triggerTypeTime;
        }
        set
        {
            _triggerTypeTime = value;
            OnPropertychanged("TriggerTypeTime");
            SetTriggerTypeValue(!_triggerTypeTime);
        }
    }

    public TriggerViewModel()
    {
        _triggerTypeValue = false;
        _triggerTypeTime = true;
    }

    private void SetTriggerTypeTime(bool value)
    {
        _triggerTypeTime = value;
        OnPropertychanged("TriggerTypeTime");
    }

    private void SetTriggerTypeValue(bool value)
    {
        _triggerTypeValue = value;
        OnPropertychanged("TriggerTypeValue");
    }

    private void OnPropertychanged(string propertyName)
    {
        if(PropertyChanged!= null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

For XAML

<RadioButton Margin="5,1" GroupName="groupValueOrTime" Name="radioButtonTimeDriven" 
             VerticalAlignment="Top" IsChecked="{Binding Path=TriggerType}"  
             Grid.Column="0" Grid.Row="0">
     Time Driven 
</RadioButton>

<RadioButton Margin="5,1" GroupName="groupValueOrTime" Name="radioButtonValueDriven" 
             VerticalAlignment="Top" Grid.Column="0" Grid.Row="1" 
             IsChecked="{Binding Path=TriggerType}">
      Value Driven
<RadioButton>

Note: This approach removes Converters and allow you to keep your business logic in central view model.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文