Marshal
Marshal

Reputation: 6671

A Simple Wpf MVVM Binding Issue

I am trying my hands on WPF MVVM. I have written following code in XAML

<UserControl x:Class="Accounting.Menu"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"  
             xmlns:local="clr-namespace:Accounting"
             mc:Ignorable="d" 
             d:DesignHeight="105" d:DesignWidth="300">
    <UserControl.DataContext>
        <local:MenuViewModel/>
    </UserControl.DataContext>
    <StackPanel>
       <StackPanel>
                <TextBlock Text="{Binding Path=MenuHeader}"/>
       </StackPanel>
       <ListBox ItemsSource="{Binding Path=MenuItems}" Height="70"/>             
    </StackPanel>     
</UserControl>

I have got a MenuViewModel with properties MenuHeader and MenuItems. I get values in both the properties during runtime. Former is bound to text of TextBlock and latter to ItemSource of ListBox. But when I run the solution, TextBlock and ListBox are empty.

Edit: Code of ViewModel

  public class MenuViewModel: ViewModelBase
    {
        AccountingDataClassesDataContext db;

        private string _menuType;
        public string MenuHeader { get; set; }
        public ObservableCollection<string> MenuItems { get; set; }

        public MenuViewModel()
        { 

        }

        public MenuViewModel(string menuType)
        {
            this._menuType = menuType;
            db = new AccountingDataClassesDataContext();
            if (menuType == "Vouchers")
            {
                var items = db.Vouchers.OrderBy(t => t.VoucherName).Select(v => v.VoucherName).ToList<string>();

                if (items.Any())
                {
                    MenuItems = new ObservableCollection<string>(items);
                    MenuHeader = "Vouchers";
                }
            }
            else
            {
                System.Windows.MessageBox.Show("Menu not found");
            }

        }
    }

Thanks in advance.

Upvotes: 2

Views: 941

Answers (2)

user777375
user777375

Reputation: 66

I think you have to trigger the OnPropertyChanged event. I am not sure if you are using a MVVM library (since you inherit from ViewModelBase you might be using MVVM Light for example), there they wrap the OnPropertyChanged in the RaisePropertyChanged event handler. Triggering the event will inform WPF to update the UI.

string m_MenuHeader;
public string MenuHeader 
{ 
    get
    {
        return m_MenuHeader;
    } 
    set
    {
        m_MenuHeader=value; OnPropertyChanged("MenuHeader");
    }
}

Upvotes: 1

GazTheDestroyer
GazTheDestroyer

Reputation: 21261

You are creating your ViewModel in the XAML using your ViewModel's default contructor which does nothing. All your population code is in the non-default contructor which is never called.

The more usual way is to create the ViewModel in code, and inject it into the view either explicitly using View.DataContext = ViewModel, or impllcitly using a DataTemplate.

Upvotes: 3

Related Questions