2010-07-18 8 views
2

Ma tentative (ci-dessous) échoue:WPF modifier le contenu de bouton sur l'événement ViewModel.PropertyChanged

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

J'essaie d'obtenir le bouton pour changer lorsque la propriété IsReadOnly sur les changements de ViewModel (il se déclenche INotifyPropertyChanged.PropertyChanged avec "IsReadOnly" en tant que PropertyName). Qu'est-ce que je rate?

.NET 3.5

ANSWER (au moins pour moi - ne supporte pas le cas général):

Je viens d'écrire un convertisseur rapide pour la liaison propriété booléenne.

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

Répondre

2

Si vous définissez la propriété "Contenu" du bouton, vous ne pouvez pas le modifier avec un déclencheur, car le premier a la priorité. Essayez de supprimer le paramètre de contenu et cela devrait fonctionner, car les déclencheurs feront le bon travail eux-mêmes.

+0

Que faire vous voulez dire par "ça devrait marcher"? Définir le contenu est ce que j'essaie d'accomplir. Si vous ne pouvez pas le changer avec un déclencheur, alors je ne vois pas comment cela est possible du tout. –

+0

Votre déclencheur définit le contenu dans tous les cas, en fonction de la valeur de la propriété IsReadOnly. Vous n'avez pas besoin de définir le contenu de votre bouton. Donnez-lui le style LockButtonStyle et voyez ce qu'il se passe. –

0

Vous utilisez C#, ce qui signifie que la méthode ToString() pour les booléens retourne "true" et "false" alors que VB.NET "True" et "False".

Votre code original fonctionnera si vous changez vos déclencheurs pour utiliser les minuscules "vrai" et "faux" au lieu des majuscules "Vrai" et "Faux".

Testé avec ce code ...

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# pour la fenêtre:

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

C# pour la classe 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")); 
     } 
    } 
} 
Questions connexes