简体   繁体   中英

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.

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.

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");
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM