【问题标题】:Prism: Commanding Delegate<T>棱镜:指挥官<T>
【发布时间】:2010-11-24 18:08:54
【问题描述】:

我有一个 ViewModel 作为数据上下文的视图(在代码中设置)。在我看来,我有一个列表

<UserControl x:Class="ZPOS.Modules.Menu.Views.DepartmentView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation">
    <Grid>
<Grid.Background>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF9CA48A"/>
                <GradientStop Color="#FFFFFFFF" Offset="1"/>
                <GradientStop Color="#FF90A85C" Offset="0.5"/>
            </LinearGradientBrush>
        </Grid.Background>
        <ListBox ItemsSource="{Binding Departments}"
                 SelectionChanged="ListBox_SelectionChanged">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.Background>
                            <LinearGradientBrush>
                                <GradientStop Color="Black" Offset="0"/>
                                <GradientStop Color="White" Offset="1"/>
                            </LinearGradientBrush>
                        </Grid.Background>
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>
                        <Button Height="Auto" HorizontalAlignment="Left" Margin="1,1,1,1" Grid.Column="0" Grid.Row="0" Content="{Binding Path=Name}"  
                                prism:Click.Command="{Binding displayMenubyCategory}" VerticalAlignment="Bottom" Width="Auto"/>
                        <TextBlock  Grid.Column="0" Grid.Row="1"   Text="{Binding Path=Note}" />
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Height="Auto" HorizontalAlignment="Left" Margin="1,1,1,1" Grid.Column="0" Grid.Row="0" Content="{Binding Path=Name}" prism:Click.Command="{Binding displayMenubyCategory}" VerticalAlignment="Bottom" Width="Auto"/>

    </Grid>
</UserControl>

视图模型

using System;
using System.ComponentModel;
using Microsoft.Practices.Composite.Events;
using System.Collections.Generic;
using ZPOS.Infrastructure;
using ZPOS.Objects;
using System.Collections.ObjectModel;
using ZPOS.Modules.Menu.Views;
using ZPOS.Contracts;
using Microsoft.Practices.Composite.Presentation.Commands;
namespace ZPOS.Modules.Menu.PresentationModels
{
    public class DepartmentViewModel : IDepartmentViewModel, INotifyPropertyChanged
    {


        private readonly IEventAggregator eventAggregator;
        private string _message;
        IMenuService service;

        public DelegateCommand<POSDepartment> displayMenubyCategory { get; private set; } 

        public string Name { get; set; }



        private ObservableCollection<POSDepartment> deptItems;
        public ObservableCollection<POSDepartment> Departments
        {
            get { return deptItems; }
            private set
            {
                if (deptItems != value)
                {
                    deptItems = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("deptItems"));
                }
            }
        }

        public string Message
        {
            get { return _message; }
            set
            {
                if (_message != value)
                {
                    _message = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("deptItems"));
                }
            }
        }



        public IDepartmentView View { get; private set; }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        private void NotifyPropertyChanged(string propertyName)
        {
            var handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }





        public DepartmentViewModel(IDepartmentView deptView, IEventAggregator eventAggregator, IMenuService service)
        {
            this.View = deptView;
            this.View.Model = this;
            this.eventAggregator = eventAggregator;
            this.service = service;
            this.Name = "View for DepartmentModel";

            this.eventAggregator.GetEvent<DepartmentSelectionChangedEvent>().Subscribe(departmentSelectionChanged);
            displayMenubyCategory = new DelegateCommand<POSDepartment>(ExecuteCommand1, CanExecuteCommand1);

            PopulateDepartmentItems();
        }


        private void ExecuteCommand1(POSDepartment commandParameter)
        {
        }

        private bool CanExecuteCommand1(POSDepartment commandParameter)
        {
            return true;
        }

        public void departmentSelectionChanged(POSDepartment item)
        {
            this.Message = item.Name;
        }



        private void PopulateDepartmentItems()
        {
            try
            {

                List<POSDepartment> items = service.GetAllDepartments();

                deptItems = new ObservableCollection<POSDepartment>(items);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }


    }
}

单击列表框内的按钮不会触发命令。

如果我将同一个按钮放在列表框外,就会调用 delage。

我是不是做错了什么?

有没有更好的方法。我还是 Prism 的新手。我还想在命令被触发时传递参数(列表框项的数据上下文)。

谢谢大家

【问题讨论】:

    标签: .net mvvm prism


    【解决方案1】:

    当你说在ListBox 内部时,我想你是在ListBoxItemTemplate 内部,对吧?

    ItemTemplate 应用于为ListBox 生成的每个项目。每个生成的项目都有一个DataContext 设置为为其生成它的数据项目。因此,该数据项需要一个名为displayMenubyCategory 的属性,否则绑定将失败。在 Visual Studio 中查看输出窗口并检查绑定错误。

    Button 移到ListBox 之外意味着不同的DataContext(您的视图模型),这意味着绑定将成功,因此一切都会正常工作。

    您的选择包括:

    1. displayMenubyCategory 属性添加到您的数据类中,这可能会调用主视图模型的相同属性。
    2. 更改您的绑定以查看当前DataContext 之外的内容(请参阅RelativeSource)。

    【讨论】:

    • @Kent- 感谢您的超快回复。我会检查 2 号。这似乎是有道理的。没有 1. 当你说 DataClass 是我的对象(PO​​SDepartment)吗?
    • @Kent - 没有 2。成功了 - 从安德森提供的样本中开始工作。我仍然想知道如何使用 Property
    • 他说您的 POSDepartment 类型可能需要一个属性来引用您可以绑定到的父视图模型上的命令。例如: public DelegateCommand displayMenubyCategory { get { return parentViewModel.displayMenubyCategory ; } }。这样做的优点是不必在 Xaml 中使用祖先绑定,但缺点是在 C# 中具有相同的间接性。这将允许您的按钮绑定返回到简单的 {Binding displayMenubyCategory}。味道比什么都重要。
    【解决方案2】:

    正如 Kent 提到的,您可以使用 RelativeSource。第一次如何使用它并不总是很清楚,所以这里有一个示例供您使用。我认为这会起作用(为简洁起见,删除了一些按钮属性):

    <Button prism:Click.Command="{Binding 
    RelativeSource={RelativeSource FindAncestor, 
    AncestorType={x:Type UserControl}}, Path=DataContext.displayMenubyCategory}" />
    

    应该这样做。它假定您将 DataContext 设置为您的父 ViewModel。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-12-06
      • 1970-01-01
      • 2016-05-10
      • 2019-02-05
      • 1970-01-01
      • 2017-01-06
      • 1970-01-01
      • 2016-01-01
      相关资源
      最近更新 更多