Search code examples
c#wpfxamlbindingattached-properties

Bind textblock visibility with custom property of grid


Hello,

After reading lots of topics about visibility binding for hours, I'm asking here because I don't manage to make my case works.

I have a grid with a custom attached property (type System.Windows.Visibily) which I want to use to display (or not) a textblock inside the grid (by binding). Also I want to change the visibility everytime the custom attached property change.

What I have done so far : CustomProperties class :

    public static class CustomProperties
    {
        public static readonly DependencyProperty starVisibilityProperty = 
            DependencyProperty.RegisterAttached("starVisibility", 
            typeof(System.Windows.Visibility), typeof(CustomProperties), 
            new FrameworkPropertyMetadata(null));

        public static System.Windows.Visibility GetStarVisibility(UIElement element)
        {
            if (element == null)
                throw new ArgumentNullException("element");
            return (System.Windows.Visibility)element.GetValue(starVisibilityProperty);
        }

        public static void SetStarVisibility(UIElement element, System.Windows.Visibility value)
        {
            if (element == null)
                throw new ArgumentNullException("element");
            element.SetValue(starVisibilityProperty, value);
        }
    }

Then here is my xaml :

            <Grid Name="server1State" Grid.Row="1" local:CustomProperties.StarVisibility="Hidden">
                <TextBlock Name="server1Star" Text="&#xf005;" FontFamily="{StaticResource fa-solid}" FontSize="30" Margin="10" Foreground="#375D81" Visibility="{Binding ElementName=server1State, Path=server1State.(local:CustomProperties.starVisibility)}"/>
            </Grid>

But when I run my app, the textblock is absolutely not hidden, this is visible, and never change. I have tried lots of things with Path and also INotifyPropertyChanged but as I am working with static custom attached property, I didn't manage to make it works.

Maybe some of you could help me, thanks.


Solution

  • Your Binding.Path on the TextBlock is wrong.

    Since I've read from your comment, that you prefer to use a boolean property, I'll show how to convert the bool value to a Visibility enumeration value using the library's BooleanToVisibilityConverter. I think you may already got it, but then got confused due to your wrong Binding.Path:

    CustomProperties.cs

    public class CustomProperties : DependencyObject
    {
      #region IsStarVisibile attached property
    
      public static readonly DependencyProperty IsStarVisibileProperty = DependencyProperty.RegisterAttached(
        "IsStarVisibile",
        typeof(bool),
        typeof(CustomProperties),
        new PropertyMetadata(default(bool)));
    
      public static void SetIsStarVisibile(DependencyObject attachingElement, bool value) => attachingElement.SetValue(CustomProperties.IsStarVisibileProperty, value);
    
      public static bool GetIsStarVisibile(DependencyObject attachingElement) => (bool)attachingElement.GetValue(CustomProperties.IsStarVisibileProperty);
    
      #endregion
    }
    

    MainWindow.xaml

    <Window>
      <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
      </Window.Resources>
    
      <Grid Name="Server1StateGrid"
            CustomProperties.IsStarVisibile="False">
        <TextBlock Text="&#xf005;" 
                   Visibility="{Binding ElementName=Server1StateGrid,       
                                Path=(CustomProperties.IsStarVisibile), 
                                Converter={StaticResource BooleanToVisibilityConverter}}" />
      </Grid>
    </Window>