kformeck
kformeck

Reputation: 1823

WPF DataBinding Issues - Possible Noob Problems

I am trying to bind a ViewModel property of type Visibility to the visibility property on a Dock Panel:

Updated ViewModel Code:

public class SelectWaferButtonViewModel : INotifyPropertyChanged
{
    private bool isClicked;

    public SelectWaferButtonViewModel()
    {
        isClicked = false;
    }

    public bool IsControlVisible
    {
        get
        {
            return isClicked;
        }
        set
        {
            isClicked = value;
            OnPropertyChanged("IsControlVisible");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnButtonClick()
    {
        if (isClicked)
        {
            IsControlVisible = false;
        }
        else
        {
            IsControlVisible = true;
        }
    }
    protected virtual void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

and here is my updated XAML code:

            <DockPanel
                Name="tvwDockPanel"
                Width="200"
                Visibility="{Binding IsControlVisible, FallbackValue=Collapsed, Converter={StaticResource BoolToVisConverter}}"
                DockPanel.Dock="Left">
                <DockPanel
                    DockPanel.Dock="Top"
                    Height="22">
                </DockPanel>

and I set the data context in the code behind with this line:

    tvwDockPanel.DataContext = btnSelectWaferViewModel;

where btnSelectWaferViewModel is the ViewModel object for this situation.

and for fun, here is my code behind:

public partial class WaferTrackerWindow : Window
{
    List<ISubscribeEvents> subscriptionList;
    SelectWaferButtonViewModel btnSelectWaferViewModel;

    public WaferTrackerWindow()
    {
        InitializeComponent();

        this.InstantiateObjects();
        this.SubscribeEvents();
        this.SetDataContexts();
    }

    #region Methods

    private void SetDataContexts()
    {
        tvwDockPanel.DataContext = btnSelectWaferViewModel.IsControlVisible;
    }
    private void SubscribeEvents()
    {
        foreach (ISubscribeEvents subscriber in subscriptionList)
        {
            subscriber.SubscribeEvents();
        }
    }
    private void InstantiateObjects()
    {
        btnSelectWaferViewModel = new SelectWaferButtonViewModel();
        subscriptionList = new List<ISubscribeEvents>();
        subscriptionList.Add(
            new Classes.WaferTrackerWindow.SelectWaferButtonView(btnSelectWafer, btnSelectWaferViewModel));
    }

    #endregion
}

All I want to do click the button btnSelectWafer and have the tvwDockPanel's visibility property to get to set to Visible via binding. Then when you click again on btnSelectWafer, tvwDockPanel's visibility property gets set back to Collapsed again. tvwDockPanel's visibility will only ever be either Collapsed or Visible.

Any help would be awesome, I am rather new to this whole data binding concept.

Upvotes: 0

Views: 703

Answers (2)

siger
siger

Reputation: 3162

The problem is that you're binding your DockPanel to the boolean property of your view model, and then setting the Visiblity property of your UI element to the IsControlVisible property of the datacontext (which doesn't exist).

Change to:

private void SetDataContexts()
{
    tvwDockPanel.DataContext = btnSelectWaferViewModel;
}

Upvotes: 0

Fede
Fede

Reputation: 44028

You have several issues here:

First of all, the intent of MVVM (if you're trying to do this with MVVM) is to separate logic from presentation. This means that in no way your ViewModel can have a reference to System.Windows.Controls.Button, nor to System.Windows.Visibility, nor to any other classes inside the System.Windows Namespace.

It is not clear to me what your SelectWaferButtonViewModel class is doing with the Button, but you need to remove the Button from there.

Also, If you need to manipulate the Visibility of a control from the ViewModel layer, you'd better use a Boolean property and the BooleanToVisibilityConverter in XAML:

ViewModel:

public bool IsControlVisible {get;set;} //Don't forget INotifyPropertyChanged!!

XAML:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVisConverter"/>
</Window.Resources>
<DockPanel Visibility="{Binding IsControlVisible, Converter={StaticResource BoolToVisConverter}}"/>

Upvotes: 3

Related Questions