2

In my application, I've got a stackpanel I'd like to keep hidden (or collapsed, whatever keeps it out of sight until it's needed) and it is to be made visible when the user clicks a button.

The issue I've run into, using my rudimentary knowledge of the MVVM technique, is to have the stackpanel's visibility bound to a property in my viewmodel. The property is a Visibility type, and the button uses a custom command utilizing the ICommand interface to call the method in my viewmodel which, at this stage, simply alters the value of the visibility property to which the stackpanel is bound.

I've confirmed the command itself is successfully calling the method, and the visibility property IS being changed, but the stackpanel to which I have bound the visibility property refuses to become visible.

I'll try to construct an illustrative example of the code I'm using:

<Button Content="Show StackPanel" Command="{Binding Path=ShowPanelCommand}" />
<StackPanel Visibility="{Binding Path=panelVisibility}" />

And in the method called by the Command in the viewmodel:

public Visibility panelVisibility { get; set; }

public void ShowThePanel()
{
    panelVisibility = Visibility.Visible;
}

I'm quite new to C#/.NET and programming in general.

I've learned a lot in a short amount of time, but once in a while I do hit a brick wall like this.

Some guided assistance would be invaluable to me.

I'm open to suggestions for better/more efficient techniques for achieving the result I've outlined in this question, but just the same for the benefit of my understanding I'd like to know what I missed or did wrong while trying to use this particular way.

Thanks for the help.

Shachi
  • 1,858
  • 3
  • 23
  • 41
Sandwich
  • 23
  • 3

2 Answers2

0

What you need to do is implement INotifyPropertyChanged in your ViewModel:

public class YourViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public void ShowThePanel()
    {
        PanelVisibility = Visibility.Visible;
    }

    private Visibility panelVisibility;

    public Visibility PanelVisibility
    {
        get
        {
            return panelVisibility
        }
        set
        {
            panelVisibility = value;
            OnPropertyChanged("PanelVisibility");
        }
    }
}

Then in your XAML:

<StackPanel Visibility="{Binding Path=PanelVisibility, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

EDIT:

The INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed. For example, consider a Person object with a property called FirstName. To provide generic property-change notification, the Person type implements the INotifyPropertyChanged interface and raises a PropertyChanged event when FirstName is changed. For change notification to occur in a binding between a bound client and a data source, your bound type should either:

  • Implement the INotifyPropertyChanged interface (preferred).
  • Provide a change event for each property of the bound type.

Do not do both.

Willem
  • 9,166
  • 17
  • 68
  • 92
  • @Sandwich You need a way to Notify the UI that the value of the property has changed and this is just 1 way of doing it(MVVM 101). With `OnPropertyChanged("PanelVisibility");` below your `set`, it notifies the UI of the change. When using an Automatic property, it does not notify the UI of any changes in you ViewModel. – Willem May 16 '13 at 08:52
0

Assuming that you are using .net 4 or less then and you have setup your INotifyPropertyChanged code in your viewModel base class and call it in the setter method of your panelVisibility property.

INotifyPropertyChanged is the mechanism that allows the binding to notify the listening controls to know that they need to change.

example base viewmodel

public class baseViewModel : INotifyPropertyChanged
{
    // boiler-plate
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

there is also a heap of info on how to implement and call the iNotifyPropertyChanged interface here Implementing INotifyPropertyChanged - does a better way exist?

.net 4.5 is slightly different. i havent used 4.5, so cant give feedback on it

Community
  • 1
  • 1
Anton
  • 7,709
  • 5
  • 31
  • 33