代码之家  ›  专栏  ›  技术社区  ›  Travis Heseman

WPF更改按钮内容打开ViewModel.PropertyChanged事件

  •  2
  • Travis Heseman  · 技术社区  · 16 年前

    <Canvas x:Key="Lock" ... />
    <Canvas x:Key="Unlock" ... />
    
    <Style x:Key="LockButtonStyle" TargetType="{x:Type Button}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="True">
                <DataTrigger.Setters>
                    <Setter Property="Content" Value="{StaticResource Lock}" />                           
                </DataTrigger.Setters>
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="False">
                <DataTrigger.Setters>
                    <Setter Property="Content" Value="{StaticResource Unlock}" />
                </DataTrigger.Setters>
            </DataTrigger>
        </Style.Triggers>
    </Style>
    
    ...
    
    <Button Content="{StaticResource Lock}" />
    

    我试图在ViewModel上的IsReadOnly属性更改(它在otifyPropertyChanged.PropertyChanged属性名为“IsReadOnly”。我错过了什么?

    .NET 3.5版

    回答(至少对我来说-不支持一般情况):

    [ValueConversion(typeof(bool), typeof(object))]
    public class BooleanValueConverter : IValueConverter
    {
        public object FalseValue { get; set; }
        public object TrueValue { get; set; }
    
        #region IValueConverter Members
    
        public object Convert(object value, Type targetType, 
                              object parameter, CultureInfo culture)
        {
            return (bool)value ? this.TrueValue : this.FalseValue;
        }
    
        public object ConvertBack(object value, Type targetType, 
                                  object parameter, CultureInfo culture)
        {
            return object.Equals(this.TrueValue, value) ? true : false;
        }
    
        #endregion
    }
    
    ...
    
    <local:BooleanValueConverter x:Key="LockOrUnlock" 
        TrueValue="{StaticResource Unlock}" 
        FalseValue="{StaticResource Lock}" />
    
    ...
    
    <Button Content="{Binding Path=IsReadOnly, 
                                 Converter={StaticResource LockOrUnlock}}" />
    
    2 回复  |  直到 16 年前
        1
  •  4
  •   Maurizio Reginelli    16 年前

    如果设置按钮的属性“Content”,则不能用触发器更改它,因为第一个优先。
    尝试删除内容的设置,它应该可以工作,因为触发器本身会做正确的工作。

        2
  •  2
  •   Frinavale    8 年前

    如果您将触发器更改为使用小写的“true”和“false”,而不是大写的“true”和“false”,则原始代码将正常工作。

    XAML:

    <Window.Resources>
         <local:ViewModel x:Key="TheViewModel" />
        <Canvas x:Key="Lock">
            <TextBlock Text="Lock"/>
        </Canvas>
        <Canvas x:Key="Unlock">
            <TextBlock Text="Unlock"/>
        </Canvas>
    
        <Style x:Key="LockButtonStyle" TargetType="{x:Type Button}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="true">
                    <DataTrigger.Setters>
                        <Setter Property="Content" Value="{StaticResource Lock}" />
                    </DataTrigger.Setters>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="false">
                    <DataTrigger.Setters>
                        <Setter Property="Content" Value="{StaticResource Unlock}" />
                    </DataTrigger.Setters>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Resources>
    <Grid DataContext="{StaticResource TheViewModel}">
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        <Button x:Name="LockButton" Style="{StaticResource LockButtonStyle}" />
        <Button x:Name="ChangeIsReadOnly" Content="Change State" Grid.Row="1" Click="ChangeIsReadOnly_Click"/>
    </Grid>
    

    对于窗户:

    public MainWindow()
    {
        InitializeComponent();
    }
    private void ChangeIsReadOnly_Click(object sender, RoutedEventArgs e)
    {
        ViewModel theViewModel = (ViewModel)FindResource("TheViewModel");
        theViewModel.IsReadOnly = !theViewModel.IsReadOnly;
    }
    

    对于ViewModel类:

    public class ViewModel : System.ComponentModel.INotifyPropertyChanged
    {
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    
        private bool isReadOnly;
        public bool IsReadOnly
        {
            get
            {
                return isReadOnly;
            }
            set 
            {
                isReadOnly = value;
                PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("IsReadOnly"));
            }
        }
    }