一个简单的 wpf MVVM 绑定问题

本文关键字:wpf MVVM 绑定 问题 简单 一个 | 更新日期: 2023-09-27 18:30:33

我正在尝试WPF MVVM。我用 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>

我有一个MenuViewModelMenuHeaderMenuItems属性。我在运行时获取两个属性中的值。前者绑定到TextBlock的文本,后者绑定到ListBox的项源。但是当我运行解决方案时,文本块和列表框是空的。

编辑:视图模型的代码

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

提前谢谢。

一个简单的 wpf MVVM 绑定问题

您正在使用 ViewModel 的默认构造器在 XAML 中创建视图模型,该构造器不执行任何操作。您的所有填充代码都在永远不会调用的非默认构造器中。

更常见的方法是在代码中创建 ViewModel,并使用 View.DataContext = ViewModel 显式地将其注入到视图中,或者使用 DataTemplate 显式地注入视图。

我认为你必须触发OnPropertyChanged事件。我不确定您是否正在使用MVVM库(例如,由于您从ViewModelBase继承,因此您可能正在使用MVVM Light),他们将OnPropertyChanged包装在RaisePropertyChanged事件处理程序中。触发事件将通知 WPF 更新 UI。

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