Override value from data binding through attached property

1 day ago 1
ARTICLE AD BOX

I have a control with a binding to its Visibility property. I would like to override the binding through an attached property, whenever a certain condition is fullfilled. However, the binding is still executed after SetValue in the attached property: The debugger shows an access to the getter of ButtonVisibility.


Minimal example showing the behavior:

MainWindow.xaml:

<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApp1" Height="160" Width="360"> <StackPanel Margin="20"> <Button Content="Correctly hidden" Visibility="Visible" local:Permission.HideIfNot="some-complex-permission-expression" /> <Button Content="Should be hidden, but is visible" Visibility="{Binding ButtonVisibility}" local:Permission.HideIfNot="some-complex-permission-expression" /> </StackPanel> </Window>

MainWindow.xaml.cs:

public partial class MainWindow { public MainWindow() { DataContext = new ViewModel(); InitializeComponent(); } } public class ViewModel : INotifyPropertyChanged { public Visibility ButtonVisibility => Visibility.Visible; public event PropertyChangedEventHandler? PropertyChanged; } public static class Permission { public static readonly DependencyProperty HideIfNotProperty = DependencyProperty.RegisterAttached( "HideIfNot", typeof(string), typeof(Permission), new PropertyMetadata("", OnHideIfNotChanged)); public static string GetHideIfNot(DependencyObject d) => (string)d.GetValue(HideIfNotProperty); public static void SetHideIfNot(DependencyObject d, string value) => d.SetValue(HideIfNotProperty, value); private static void OnHideIfNotChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is UIElement element && e.NewValue is "some-complex-permission-expression") { BindingOperations.ClearBinding(d, UIElement.VisibilityProperty); element.SetValue(UIElement.VisibilityProperty, Visibility.Collapsed); } } }

Result:

Form showing the second button, though it should be hidden

Both buttons should be hidden.

How can one reliably override a binding through an attached property?


Note: I've already solved my actual problem through a MarkupExtension, but I am still curious why the binding could not be overwritten. It seems I misunderstood something about how WPF internally works.

Read Entire Article