2010-08-24 8 views
1

J'ai un code simple ci-dessous qui utilise une propriété ToggleButton.IsChecked pour définir la visibilité d'un TextBlock. Ça fonctionne bien. Comme cela ne correspond pas tout à fait à la structure de mon programme, j'essaye de lier la visibilité d'un autre TextBlock à un DependencyProperty de "this". Il compile bien, mais il ne produit aucun effet. Je fais quelque chose de mal, je ne sais pas quoi.Liaison de visibilité à l'aide de DependencyProperty

XAML

<Window x:Class="ToggleButtonTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Width="200" Height="100"> 
<Window.Resources> 
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> 
</Window.Resources> 
<StackPanel> 
    <ToggleButton x:Name="toggleButton" Content="Toggle" 
        IsChecked="True" Checked="toggleButton_Checked"/> 
    <TextBlock Text="Some Text" 
       Visibility="{Binding IsChecked, 
       ElementName=toggleButton, 
       Converter={StaticResource BooleanToVisibilityConverter}}"/> 
    <TextBlock Text="More Text" 
       Visibility="{Binding ShowMoreText, 
       ElementName=this, 
       Converter={StaticResource BooleanToVisibilityConverter}}"/> 
</StackPanel> 
</Window> 

C#

using System.Windows; 

namespace ToggleButtonTest 
{ 
    public partial class MainWindow : Window 
    { 
     static MainWindow() 
     { 
      FrameworkPropertyMetadata meta = 
       new FrameworkPropertyMetadata(true, 
       FrameworkPropertyMetadataOptions.BindsTwoWayByDefault); 

      ShowMoreTextProperty = 
       DependencyProperty.Register("ShowMoreText", 
       typeof(bool), typeof(MainWindow), meta); 
     } 

     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     public static readonly DependencyProperty ShowMoreTextProperty; 
     public bool ShowMoreText 
     { 
      get 
      { 
       return (bool)GetValue(ShowMoreTextProperty); 
      } 
      set 
      { 
       SetValue(ShowMoreTextProperty, value); 
      } 
     } 

     private void toggleButton_Checked(object sender, RoutedEventArgs e) 
     { 
      ShowMoreText = toggleButton.IsChecked.Value; 
     } 
    } 
} 

Edit:

Ayant eu cette réponse, je veux poster mon code de travail ...

XAML

<Window x:Class="ToggleButtonTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Width="200" Height="100" 
    Name="thisWindow"> 
    <Window.Resources> 
     <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> 
    </Window.Resources> 
    <StackPanel> 
     <ToggleButton x:Name="toggleButton" 
       Content="Toggle" 
       IsChecked="{Binding Path=ShowMoreText, ElementName=thisWindow}"/> 
     <TextBlock Text="More Text" 
        Visibility="{Binding Path=ShowMoreText, 
        ElementName=thisWindow, 
        Converter={StaticResource BooleanToVisibilityConverter}}"/> 
    </StackPanel> 
</Window> 

C#

using System.Windows; 

namespace ToggleButtonTest 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     public static readonly DependencyProperty ShowMoreTextProperty = 
      DependencyProperty.Register("ShowMoreText", typeof(bool), 
      typeof(MainWindow), new FrameworkPropertyMetadata(true, 
       FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 

     public bool ShowMoreText 
     { 
      get 
      { 
       return (bool)GetValue(ShowMoreTextProperty); 
      } 
      set 
      { 
       SetValue(ShowMoreTextProperty, value); 
      } 
     } 
    } 
} 

Répondre

11

ElementName doit vraiment être un nom d'élément. this ne vole pas. Heureusement, vous avez un élément de type MainWindow ici avec une propriété ShowMoreText: l'élément racine Window.

Donnez le Window un nom et l'utiliser comme ElementName, comme ci-dessous:

<Window x:Class="ToggleButtonTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Width="200" Height="100" 
    x:Name="thisWindow"> 
<Window.Resources> 
    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/> 
</Window.Resources> 
<StackPanel> 
    <ToggleButton x:Name="toggleButton" Content="Toggle" 
         IsChecked="True" Checked="toggleButton_Checked"/> 
    <TextBlock Text="Some Text" 
        Visibility="{Binding IsChecked, 
        ElementName=toggleButton, 
        Converter={StaticResource BooleanToVisibilityConverter}}"/> 
    <TextBlock Text="More Text" 
        Visibility="{Binding ShowMoreText, 
        ElementName=thisWindow, 
        Converter={StaticResource BooleanToVisibilityConverter}}"/> 
</StackPanel> 
</Window> 

Notez que vous pouvez faire la même chose en utilisant RelativeSource Self, mais je préfère la méthode ci-dessus.

+0

+1. Il convient également de mentionner que l'utilisation de "this" en tant qu'argument ElementName ne fera pas référence au même "this" que C#. – rossisdead

+0

Merci! Cela a du sens maintenant. Je n'avais pas envisagé de donner un nom à la fenêtre. Malheureusement, cela ne semble pas avoir résolu le problème. Toujours en train de regarder ... – Nate

1

Donnez votre fenêtre un nom et définissez le ElementName à ce nom, au lieu d'utiliser « ce ».

2

La façon dont vous l'avez configuré actuellement ne définira jamais ShowMoreText sur false. Le gestionnaire Checked ne sera appelé que lorsque IsChecked de ToggleButton passe de false à true. Pour aller aussi dans l'autre sens, vous avez besoin d'un gestionnaire pour non vérifié aussi bien. La meilleure façon de gérer cette situation serait de mettre en place une liaison sur le ToggleButton qui fera à la fois sans gestionnaires d'événements (en utilisant les changements de Jay):

IsChecked="{Binding Path=ShowMoreText, ElementName=thisWindow}" 
+0

Excellent. Je ne faisais pas attention que l'événement Checked est arrivé seulement quand c'était vrai. Entre ta réponse et celle de Jay, j'ai pu résoudre ça. Je vous remercie. – Nate

Questions connexes