我使用 IValueConverter 设置复选框。 但是我有三个复选框,我像单选按钮一样使用。选择一个时,需要取消选中另一个。
所以我做了类似的事情>
<MenuItem StaysOpenOnClick="True"
Header="Reiniciar áudio"
IsCheckable="True"
Name="RestartAudioCheck"
IsChecked="{Binding PlayType,
Mode=TwoWay,
Converter={StaticResource PlayTypeCheckedConverter},
ConverterParameter=restart}">
</MenuItem>
<MenuItem StaysOpenOnClick="True"
Header="Parar áudio"
IsCheckable="True"
Name="StopAudioCheck"
IsChecked="{Binding PlayType,
Mode=TwoWay,
Converter={StaticResource PlayTypeCheckedConverter},
ConverterParameter=stop}">
</MenuItem>
<MenuItem StaysOpenOnClick="True"
Header="Pausar áudio"
IsCheckable="True"
Name="PauseAudioCheck"
IsChecked="{Binding PlayType,
Mode=TwoWay,
Converter={StaticResource PlayTypeCheckedConverter},
ConverterParameter=pause}">
</MenuItem>
和转换器:
class PlayTypeCheckedConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is PlayType type))
return false;
if (!(parameter is string check))
return false;
if (check.CompareTo("restart") == 0 && type == PlayType.Restart)
return true;
if (check.CompareTo("stop") == 0 && type == PlayType.Stop)
return true;
if (check.CompareTo("pause") == 0 && type == PlayType.Pause)
return true;
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (!(value is bool isChecked))
return true;
if (!(parameter is string type))
return PlayType.Restart;
if (type.CompareTo("restart") == 0 && isChecked)
return PlayType.Restart;
if (type.CompareTo("stop") == 0 && isChecked)
return PlayType.Stop;
if (type.CompareTo("pause") == 0 && isChecked)
return PlayType.Pause;
return PlayType.Restart;
}
}
我的问题是:将像绝对文本这样的转换器参数作为示例来了解转换器上的内容是错误的? 就像我做得很好一样。
可以为任何属性类型使用单个相等转换器。使用它的诀窍是传递特定类型的参数,而不是字符串表示。
转换器:
public class EqualityCheckConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Equals(value, parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (Equals(value, true))
return parameter;
return Binding.DoNothing;
}
}
enum
示例:
// property to bind
public DayOfWeek Day { get; set; }
捆绑:
<Window.Resources>
<wpfDemos:EqualityCheckConverter x:Key="EqualCheckedConverter"/>
</Window.Resources>
<Menu>
<MenuItem StaysOpenOnClick="True"
Header="Tuesday"
IsCheckable="True"
IsChecked="{Binding Day,
Mode=TwoWay,
Converter={StaticResource EqualCheckedConverter},
ConverterParameter={x:Static system:DayOfWeek.Tuesday}}"/>
<MenuItem StaysOpenOnClick="True"
Header="Wednesday"
IsCheckable="True"
IsChecked="{Binding Day,
Mode=TwoWay,
Converter={StaticResource EqualCheckedConverter},
ConverterParameter={x:Static system:DayOfWeek.Wednesday}}"/>
<MenuItem StaysOpenOnClick="True"
Header="Thursday"
IsCheckable="True"
IsChecked="{Binding Day,
Mode=TwoWay,
Converter={StaticResource EqualCheckedConverter},
ConverterParameter={x:Static system:DayOfWeek.Thursday}}"/>
</Menu>
带有int
的示例
public int TestNum { get; set; }
<Window.Resources>
<wpfDemos:EqualityCheckConverter x:Key="EqualCheckedConverter"/>
<system:Int32 x:Key="Zero">0</system:Int32>
<system:Int32 x:Key="Ten">10</system:Int32>
</Window.Resources>
<Menu>
<MenuItem StaysOpenOnClick="True"
Header="0"
IsCheckable="True"
IsChecked="{Binding TestNum,
Mode=TwoWay,
Converter={StaticResource EqualCheckedConverter},
ConverterParameter={StaticResource Zero}}"/>
<MenuItem StaysOpenOnClick="True"
Header="10"
IsCheckable="True"
IsChecked="{Binding TestNum,
Mode=TwoWay,
Converter={StaticResource EqualCheckedConverter},
ConverterParameter={StaticResource Ten}}"/>
</Menu>
像您那样显式比较字符串文字通常被认为是一种不好的做法。无论是否使用 WPF,原因显而易见,它都容易出现运行时错误,并且不存在类型检查。
我能想到两种解决方案:
- 最常见的方法是在视图模型中添加三个属性,如果状态满足,则只使用基本上返回 true 或 false 的 getter。然后,您可以在播放状态更改时引发所有这三个布尔属性的属性更改。
从这个视图模型的例子中,你可以绑定到视图中的每个复选框,它们各自的属性(IsPlaying
、IsStopped
、IsPaused
(:
private State _playState;
public State PlayState
{
get { return _playState; }
set {
SetProperty(ref _playState, value);
RaisePropertyChanged(nameof(IsPlaying));
RaisePropertyChanged(nameof(IsPaused));
RaisePropertyChanged(nameof(IsStopped));
}
}
public bool IsPlaying
{
get { return _playState == State.Playing; }
}
public bool IsPaused
{
get { return _playState == State.Paused; }
}
public bool IsStopped
{
get { return _playState == State.Stopped; }
}
- 在
- XAML 中使用 PlayState 属性上的复选框的
DataTrigger
。然后,可以检查类型化的枚举值,而不是字符串文本。