【问题标题】:Is there an easy way to bind a command to a listbox in MVVM WPF?有没有一种简单的方法可以将命令绑定到 MVVM WPF 中的列表框?
【发布时间】:2011-07-28 15:33:02
【问题描述】:

我一直在尝试按照 MVVM 开发模式在 WPF 中创建一个相当简单的应用程序,但我一直在为做简单的事情似乎有多困难而发疯。我已经在 Forms 中创建了这个应用程序并成功运行,但我的老板要求我在 WPF 中重写界面作为该技术的演示。我决定尝试尽可能多地遵循最佳实践,以使应用程序和代码尽可能具有教育意义。我目前的困境是每次选择更改时都使用列表框运行一些代码。我已经准备好使用带有事件的代码隐藏来调用视图模型上的方法。对我来说,这似乎本质上仍然是 MVVM,因为没有执行任何逻辑。感谢您的帮助/见解。

【问题讨论】:

    标签: c# wpf mvvm


    【解决方案1】:

    您可以简单地绑定列表框的 selecteditem 属性...在选择更改时,视图模型中的设置器将被调用,您可以做任何您想做的事情...

    这是一个可以帮助你的示例

    XAML

      <Grid Canvas.Left="0" Canvas.Bottom="0" Height="300" Width="300" Background="Bisque">
                <ListBox ItemsSource="{Binding Employes}" SelectedItem="{Binding SelectedEmploye}"/>
            </Grid>
    

    查看模型

    public  class ViewModel : ViewModelBase
        {
            private List<Employee> _employes;
    
            public List<Employee> Employes
            {
                get { return _employes; }
                set { _employees = value; OnPropertyChanged("Employes"); }
            }
            private Employee _selectedEmploye;
    
            public Employee SelectedEmploye
            {
                get { return _selectedEmploye; }
                set
                {
                    _selectedEmployee = value;
                    OnPropertyChanged("SelectedEmploye");
                }
            }
    
        }
    

    查看模型库

    public  class ViewModelBase : INotifyPropertyChanged
        {
            protected virtual void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
        }
    

    员工类

    public class Employee : ViewModelBase
        {
            private string _name;
            public string Name
            {
                get { return _name; }
                set { _name = value; }
            }
        }
    

    【讨论】:

    • 这确实有助于为我指明正确的方向。谢谢。
    • 其实很好。但是当你不幸有一个很好的解决方法时,比如Loaded事件,你需要一些EventToCommand框架。
    【解决方案2】:

    在您的 ViewModel 中,您可以创建一个属性“SelectedItem”。如果您的 ListBox 到您的属性,则将 SelectedItem 属性绑定。

    • 如果它是 POCO clr 属性 (INotifyPropertyChanged),那么您可以从属性设置器触发您的代码。
    • 如果它是一个 DependencyProperty,您必须添加一个 PropertyChangedCallback 并从那里触发您的代码。

    【讨论】:

      【解决方案3】:

      不要害怕使用代码隐藏。没有代码隐藏是避免在视图中放置过多逻辑的指导方针,而不是硬性规定。在这种情况下(正如其他人所建议的),您可以将 SelectedItem 属性绑定到视图模型上的某个属性。对于非数据相关事件,我的建议是正常处理事件并将执行逻辑委托给视图模型。

      在我看来,设计模式应始终作为经验法则,并在使用时进行一些判断,因为很容易将它们过于严格地应用在它们不属于的领域,这通常会使事情变得更糟。

      【讨论】:

      • 我倾向于同意你的观点,但幸运的是,看起来有一些更简单的方法可以做到这一点,而无需跳过所有我认为我必须做的事情。
      • @pauleck1 - 如果您觉得自己在无谓地跳跃,可能是时候退后一步,重新考虑您是否采取了正确的方法。有了所有的 MVVM 框架,很容易无可救药地过度设计事物并使您的代码更难维护(这在某种程度上违背了目的)。并不是说 MVVM 不好,它肯定是我使用 WPF 时的首选武器。
      【解决方案4】:

      检查Galasoft MVVM Light 中的EventToCommand 行为

      Here's the SO post

      【讨论】:

      • 我必须深入检查一下。不过,我真的希望避免在项目中添加另一个框架。
      【解决方案5】:

      您可以绑定到 ListBox.SelectedItem 以在您的虚拟机中获取所选项目。

      【讨论】:

        猜你喜欢
        • 2014-07-30
        • 2011-10-17
        • 2016-03-30
        • 2016-09-24
        • 1970-01-01
        • 2011-10-26
        • 1970-01-01
        • 2011-02-17
        • 1970-01-01
        相关资源
        最近更新 更多