2010-07-18 106 views
2

我尝试(如下图)失败:WPF变化按钮内容

 
<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}" /> 

我试图让按钮更改当在视图模型的变化IsReadOnly属性(它触发INotifyPropertyChanged.PropertyChanged与“IsReadOnly”作为PropertyName)。我错过了什么?

.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

如果设置了按钮的财产“内容”,你不能用一个触发改变它,因为第一个优先。
尝试删除内容的设置,它应该工作,因为触发器会自己做正确的工作。

+0

什么做你的意思是“它应该工作”?设置内容是我想要完成的。如果你不能用触发器来改变它,那么我就不会看到这是可能的。 – 2010-07-18 14:48:46

+0

触发器根据IsReadOnly属性的值设置内容。您无需在按钮中设置内容。给它的风格LockButtonStyle,看看会发生什么。 – 2010-07-19 19:07:14

0

您正在使用C#,这意味着布尔值的ToString()方法返回“true”和“false”;而VB.NET则是“True”和“False”。

如果您将触发器更改为使用小写“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> 

C#的窗口:

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

C#的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")); 
     } 
    } 
}