WPF 与转换器的绑定不起作用
WPF Binding with converter does not work
我正在尝试将 XAML 中的某些属性与枚举类型绑定。
它应该如何工作:我在菜单栏中有一些单选按钮,用于设置我的枚举值。并且此枚举值在 Grid
中设置 isEnabled
属性。所以有一个关系:radiobutton ->(EnumToBooleanConverter)-> enum object ->(EnumToIsActiveCnoverter)-> isEnabled
attribute。我已经编写了两个转换器来执行该绑定。
代码:
<Window.Resources>
<local:EnumToBooleanConverter x:Key="actionConverter" />
<local:EnumToIsActiveConverter x:Key="activityConverter" />
</Window.Resources>
...
<MenuItem Header="Settings">
<MenuItem Header="Action">
<MenuItem Header="Draw">
<MenuItem.Icon>
<RadioButton GroupName="MenuActionButton"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Draw}}"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Edit">
<MenuItem.Icon>
<RadioButton GroupName="MenuActionButton"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Edit}}"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Constraints">
<MenuItem.Icon>
<RadioButton GroupName="MenuActionButton"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Constraints}}"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</MenuItem>
CS 文件:
public partial class MainWindow : Window
{
public ApplicationMode appMode { get; set; }
public MainWindow()
{
this.appMode = ApplicationMode.Draw;
InitializeComponent();
}
}
public class EnumToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//return value.Equals(parameter);
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value.Equals(true) ? parameter : Binding.DoNothing;
}
}
public class EnumToIsActiveConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value.Equals(parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//return value.Equals(true) ? parameter : Binding.DoNothing;
return Binding.DoNothing;
}
}
public enum ApplicationMode
{
Draw,
Edit,
Constraints
}
EnumToBooleanConverter
检查放射性参数时,将枚举值更改为给定参数,并且EnumToIsActiveConverter
更改isEnabled
给定元素的属性将枚举值设置为给定参数。
在我看来它应该工作得很好。我在这里缺少什么?
您正在使用 RadioButton
控件,但仅用作指示器。
所以点击项目不会改变 属性 值,因为只有 MenuItem
收到点击,而不是 RadioButton。
也有点浪费,因为对于 V(当前活动指示)您不需要 RadioButton 控件,而是一个具有可见性绑定的 Path。
我会用现有的方式给你一个解决方案:
一个。为每个 MenuItem 添加 Click 事件
b。将相关值放入标签 属性(这是为了简化事件,您将看到)
c。添加到您的 MainWindow class 实现 INotifyPropertyChanged
接口以允许 XAML 知道 appMode 修改。
这里是代码,XAML:
<MenuItem Header="Draw" Click="MenuItem_Click" Tag="{x:Static local:ApplicationMode.Draw}" >
<MenuItem.Icon>
<RadioButton GroupName="MenuActionButton"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Draw}}"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Edit" Click="MenuItem_Click" Tag="{x:Static local:ApplicationMode.Edit}">
<MenuItem.Icon>
<RadioButton GroupName="MenuActionButton"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Edit}}"/>
</MenuItem.Icon>
</MenuItem>
点击事件的MenuItem_Click:
public event PropertyChangedEventHandler PropertyChanged;
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
var item = (MenuItem)sender;
appMode = (ApplicationMode) item.Tag;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(appMode)));
}
更简单的解决方案,没有 RadioButton:
一个。将 MenuItem Checkable 功能用于图标作业,并将 IsChecked 绑定到 appMode 属性:
<MenuItem Header="Action">
<MenuItem Header="Draw" IsCheckable="True"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Draw}}" />
<MenuItem Header="Edit" IsCheckable="True"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Edit}}" />
</MenuItem>
b。在代码中,更改 属性 以触发 PropertyChange 事件:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private ApplicationMode _appMode;
public ApplicationMode appMode
{
get { return _appMode; }
set
{
_appMode = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(appMode)));
}
}
public MainWindow()
{
this.appMode = ApplicationMode.Draw;
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
}
c。在转换器中修复 ConvertBack 方法:
public class EnumToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value.Equals(parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return parameter;
}
}
我正在尝试将 XAML 中的某些属性与枚举类型绑定。
它应该如何工作:我在菜单栏中有一些单选按钮,用于设置我的枚举值。并且此枚举值在 Grid
中设置 isEnabled
属性。所以有一个关系:radiobutton ->(EnumToBooleanConverter)-> enum object ->(EnumToIsActiveCnoverter)-> isEnabled
attribute。我已经编写了两个转换器来执行该绑定。
代码:
<Window.Resources>
<local:EnumToBooleanConverter x:Key="actionConverter" />
<local:EnumToIsActiveConverter x:Key="activityConverter" />
</Window.Resources>
...
<MenuItem Header="Settings">
<MenuItem Header="Action">
<MenuItem Header="Draw">
<MenuItem.Icon>
<RadioButton GroupName="MenuActionButton"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Draw}}"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Edit">
<MenuItem.Icon>
<RadioButton GroupName="MenuActionButton"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Edit}}"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Constraints">
<MenuItem.Icon>
<RadioButton GroupName="MenuActionButton"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Constraints}}"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</MenuItem>
CS 文件:
public partial class MainWindow : Window
{
public ApplicationMode appMode { get; set; }
public MainWindow()
{
this.appMode = ApplicationMode.Draw;
InitializeComponent();
}
}
public class EnumToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//return value.Equals(parameter);
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value.Equals(true) ? parameter : Binding.DoNothing;
}
}
public class EnumToIsActiveConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value.Equals(parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//return value.Equals(true) ? parameter : Binding.DoNothing;
return Binding.DoNothing;
}
}
public enum ApplicationMode
{
Draw,
Edit,
Constraints
}
EnumToBooleanConverter
检查放射性参数时,将枚举值更改为给定参数,并且EnumToIsActiveConverter
更改isEnabled
给定元素的属性将枚举值设置为给定参数。
在我看来它应该工作得很好。我在这里缺少什么?
您正在使用 RadioButton
控件,但仅用作指示器。
所以点击项目不会改变 属性 值,因为只有 MenuItem
收到点击,而不是 RadioButton。
也有点浪费,因为对于 V(当前活动指示)您不需要 RadioButton 控件,而是一个具有可见性绑定的 Path。
我会用现有的方式给你一个解决方案:
一个。为每个 MenuItem 添加 Click 事件
b。将相关值放入标签 属性(这是为了简化事件,您将看到)
c。添加到您的 MainWindow class 实现 INotifyPropertyChanged
接口以允许 XAML 知道 appMode 修改。
这里是代码,XAML:
<MenuItem Header="Draw" Click="MenuItem_Click" Tag="{x:Static local:ApplicationMode.Draw}" >
<MenuItem.Icon>
<RadioButton GroupName="MenuActionButton"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Draw}}"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Edit" Click="MenuItem_Click" Tag="{x:Static local:ApplicationMode.Edit}">
<MenuItem.Icon>
<RadioButton GroupName="MenuActionButton"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Edit}}"/>
</MenuItem.Icon>
</MenuItem>
点击事件的MenuItem_Click:
public event PropertyChangedEventHandler PropertyChanged;
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
var item = (MenuItem)sender;
appMode = (ApplicationMode) item.Tag;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(appMode)));
}
更简单的解决方案,没有 RadioButton:
一个。将 MenuItem Checkable 功能用于图标作业,并将 IsChecked 绑定到 appMode 属性:
<MenuItem Header="Action">
<MenuItem Header="Draw" IsCheckable="True"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Draw}}" />
<MenuItem Header="Edit" IsCheckable="True"
IsChecked="{Binding Path=appMode,
Converter={StaticResource actionConverter},
ConverterParameter={x:Static local:ApplicationMode.Edit}}" />
</MenuItem>
b。在代码中,更改 属性 以触发 PropertyChange 事件:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private ApplicationMode _appMode;
public ApplicationMode appMode
{
get { return _appMode; }
set
{
_appMode = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(appMode)));
}
}
public MainWindow()
{
this.appMode = ApplicationMode.Draw;
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
}
c。在转换器中修复 ConvertBack 方法:
public class EnumToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value.Equals(parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return parameter;
}
}