2017-10-15 253 views
0

我想用枚举类型绑定XAML中的某些属性。 它应该如何工作:我在菜单栏中有一些单选按钮,用于设置我的枚举值。此枚举值在Grid中设置isEnabled属性。所以有一个关系:radiobutton - >(EnumToBooleanConverter) - >枚举对象 - >(EnumToIsActiveCnoverter) - >isEnabled属性。我写了两个转换器来执行该绑定。 代码:WPF与转换器绑定不起作用

<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的属性给出元素枚举值设置为给定参数时。 在我看来,它应该工作得很好。我在这里错过了什么?

回答

1

更简单的解决方案,而无需单选按钮:

一个。使用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 metode:

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; 
    } 
} 
+0

这正是我所做的! –

+0

@ wis.niowy你知道如何接受答案吗?请参阅https://stackoverflow.com/help/someone-answers。根据你的问题历史,你有很多问题可以在这里做,每一个你获得+2的声望。 – dovid

1

您正在使用RadioButton控件,但仅作为一个指标。

所以点击的作品,因为只有MenuItem收到点击,而不是单选按钮不更改属性值。

也这是一个有点浪费,因为V(电流激活指示),你并不需要一个单选按钮控制,能见度结合相当路径。

我会为你展示在现有的方式解决:

一个。向每个MenuItem添加Click事件

b。放在Tag属性相关的值(这是对事件的简单,你会看到)

℃。添加到您的MainWindow类实现的接口,以便让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的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))); 
} 
+0

因此,如果在'MenuItem_Click'中修改了appMode属性,我对'actionConverter'有什么用处?我是否需要它? –

+0

不幸的是,经过此修改之后,所有'DockPanel'元素都被启用,这意味着转换器不会更改'isEnabled'属性 –

+0

每次改变枚举属性时,PropertyChanged都为null。 –