2010-07-18 146 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")); 
     } 
    } 
}