none
User control and Binding to 'Self'

    Question

  • Hello all,

    I'm having a bit of trouble binding to a dependency property I created on a user control.  I don't get an error or any results, however, due to the default value I set for the dependency property I should be hiding a couple of controls.

    <---- c# ----->
       public partial class Information : UserControl {
            public static readonly DependencyProperty IsVisibleProperty;

            static Information() {
                Information.IsVisibleProperty = DependencyProperty.Register("IsVisible",
    typeof(Visibility), typeof(Information), new FrameworkPropertyMetadata(Visibility.Hidden, new PropertyChangedCallback(OnIsVisibleChanged)));
            }

            public Information() {
                InitializeComponent();
            }

            public Visibility IsVisible {
                get { return (Visibility)GetValue(Information.IsVisibleProperty); }
                set { SetValue(Information.IsVisibleProperty, value); }
            }
       }


    <---- Xaml ---->
    <Label Name="lblName" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Left" Visibility="{Binding RelativeSource={RelativeSource Self}, Path=IsVisible}">Label Check Name:</Label>
    <TextBox Name="txtName" Grid.Row="2" Grid.Column="1" MinWidth="240" Margin="0,4,0,4" Text="{Binding Path=Name}" Visibility="{Binding RelativeSource={RelativeSource Self}, Path=IsVisible}" />

    My hope was that by binding the Visibility property in the Xaml the specified controls would always be hidden unless I changed the IsVisible property.  Currently, I am getting no results at all out of the code.  Any help is greatly appreciated.

    Thanks,

    Corey
    Tuesday, August 28, 2007 8:19 PM

Answers


  • as Dr.WPF said your binding is wrong... you need to bind with the following code

    Visibility="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=IsVisible}"

    this will find the user control and get the property....

    Regards
    Saturday, September 01, 2007 6:11 PM
  • Note that RelativeSource.Self means a binding to the dependency object that owns the target DP.  In your former example, this is *not* your user conrol.  The target DP was the Visibility property on the TextBox, so the target DO is the TextBox, itself.  As such, you are binding the Visibility property of the TextBox to the IsVisible property of the same TextBox.  The TextBox does happen to have an IsVisible property, as do all UIElements, but there is no default type converter to translate between bool and Visibility.

     

    You should consider renaming your property, as you are introducing ambiguity between UIElement.IsVisible and your Information.IsVisible property.

     

    Also, by convention, WPF properties whose names begin with "Is", "Are", "Can", etc are of type bool.  It will likely confuse your audience if you break from this.
    Tuesday, August 28, 2007 10:51 PM

All replies

  • Just a quick update.  I was able to get the bind working by changing the Visibility property in the above xaml to the following:

    Visibility="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type props:Information}}, Path=IsLabelCheckVisible}"

    I am still trying to figure out why this works and the previous code doesn't.

    Thanks,

    Corey
    Tuesday, August 28, 2007 9:19 PM
  • Note that RelativeSource.Self means a binding to the dependency object that owns the target DP.  In your former example, this is *not* your user conrol.  The target DP was the Visibility property on the TextBox, so the target DO is the TextBox, itself.  As such, you are binding the Visibility property of the TextBox to the IsVisible property of the same TextBox.  The TextBox does happen to have an IsVisible property, as do all UIElements, but there is no default type converter to translate between bool and Visibility.

     

    You should consider renaming your property, as you are introducing ambiguity between UIElement.IsVisible and your Information.IsVisible property.

     

    Also, by convention, WPF properties whose names begin with "Is", "Are", "Can", etc are of type bool.  It will likely confuse your audience if you break from this.
    Tuesday, August 28, 2007 10:51 PM

  • as Dr.WPF said your binding is wrong... you need to bind with the following code

    Visibility="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=IsVisible}"

    this will find the user control and get the property....

    Regards
    Saturday, September 01, 2007 6:11 PM
  • I was a bit lax in my code when I first posted it.  I took the original code and modified it somewhat without really compiling or thinking about the implications of using the IsVisible property.  In my original code the user control does indeed own the dp (which, in reality, I called IsLabelCheckVisible).  I still stand mystified.
    Monday, September 10, 2007 8:14 PM