views:

2927

answers:

4

I've seen on the internet quite a few examples of binding a boolean to the Visibility property of a control in XAML. Most of the good examples use a BooleanToVisibiliy converter.

I'd like to just set the Visible property on the control to bind to a System.Windows.Visibility property in the code-behind, but it doesn't seem to want to work.

This is my XAML:

<Grid x:Name="actions" Visibility="{Binding Path=ActionsVisible, UpdateSourceTrigger=PropertyChanged}" />

This is the code for the property:

private Visibility _actionsVisible;
public Visibility ActionsVisible
{
   get
   {
      return _actionsVisible;
   }
   set
   {
      _actionsVisible = value;
   }
}

In the constructor of the Window, I also have this call:

base.DataContext = this;

When I update either ActionsVisible or this.actions.Visibility, the state doesn't transfer. Any ideas to what might be going wrong?

+5  A: 

I think the problem is that WPF can't know that your ActionsVisible property has changed since you've not notified the fact.

Your class will need to implement INotifyPropertyChanged, then in your set method for ActionsVisible you'll need to fire the PropertyChanged event with ActionsVisible as the property name that has changed.

Hope this helps...

Craig Shearer
I'm not against doing that, but I also have a TextBox bound to a string property in the code-behind and that works without the INotifyPropertyChanged event. I thought that by setting the UpdateSourceTrigger to PropertyChanged I wouldn't need to use the INotifyPropertyChanged.
Jared
Not sure how it does that then! Do you want to post more of your code? The UpdateSourceTrigger property just controls when the source (i.e. the property you're binding to) gets updated. It won't have any effect on your visibility property.
Craig Shearer
Thanks Craig. I should have been more clear on my earlier comment. I meant to say that I have a TextBox's Text property bound to a string property in the code-behind. That does work and if you still want to see the source for that then let me know.
Jared
I also wanted to thank you for telling me to use ActionsVisible as the property name, because I kept getting XamlParseExceptions when I used Visiblity as the property name and couldn't figure it out until I re-read your answer.
Jared
Glad I could help :)
Craig Shearer
+4  A: 

Change your property to be a DependencyProperty. This will handle the updating for you.

        public Visibility ActionsVisible
    {
        get { return (Visibility)GetValue(ActionsVisibleProperty); }
        set { SetValue(ActionsVisibleProperty, value); }
    }

    // Using a DependencyProperty as the backing store for ActionsVisible.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ActionsVisibleProperty =
        DependencyProperty.Register("ActionsVisible", typeof(Visibility), typeof(FooForm));
NR
When running this code in a thread other than the thread that owns it, there is an exception. The whole that I moved to binding was to allow UI elements to update from multiple threads. It doesn't seem like this solution will work for me if it has to run on a single thread.
Jared
A: 

Hi Jared

From you comment...

You have to access all controls on the thread on which they were created. You can update controls from other threads, but you have to marshall the update via the UI thread using the WPF Dispatcher.

This article should help.

Craig Shearer
A: 

write: NotifyPropertyChanged("ActionsVisible")

bedi