0

假设我有一个虚拟 WPF 应用程序(面向 MVVM)。我的主窗口包含一个我创建的自定义列表,该列表包含一个自定义项。该项目有一个图像按钮,我希望按钮命令是我在视图模型中得到的命令。视图模型绑定到主窗口。我该怎么做 ?

我附上了虚拟项目(在此处下载:http ://www.2shared.com/file/qmO3E5rx/NestedCommand.html 或此处: http: //www.multiupload.nl/KCFLSKAIH0),

但如果你不想下载它,代码如下:

主窗口 XAML:

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Application="clr-namespace:WpfApplication2"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Application:List x:Name="myList" DataContext="{Binding}" />
</Grid>

MainWindow 代码隐藏:

        public MainWindow()
    {
        InitializeComponent();
        CharacterViewModel viewModel = new CharacterViewModel();
        this.myList.ItemsList.ItemsSource = viewModel.Model.Powers;
    }

列出 XAML:

<UserControl x:Class="WpfApplication2.List"
         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:Application="clr-namespace:WpfApplication2"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
    <ListView x:Name="ItemsList" ItemsSource="{Binding Path=Name}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Application:Item x:Name="myItem" />
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

项目 XAML:

<UserControl x:Class="WpfApplication2.Item"
         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" 
         mc:Ignorable="d" 
         d:DesignHeight="50" d:DesignWidth="50">
<Grid>
    <Button x:Name="ButtonImage" Command="**????????**">
        <Button.Template>
            <ControlTemplate>
                <Border HorizontalAlignment="Center" VerticalAlignment="Center" >
                    <Image Width="50" Height="50" Source="/WpfApplication2;component/Images/Jellyfish.jpg"/>
                </Border>
            </ControlTemplate>
        </Button.Template>
    </Button>
</Grid>

视图模型代码:

    public class CharacterViewModel : ObjectBase
{
    public Character Model { get; private set; }
    public DelegateCommand<object> RemoveCommand { get; private set; }

    public CharacterViewModel()
        : this(Character.Create())
    {
    }

    public CharacterViewModel(Character model)
    {
        Model = model;
        RemoveCommand = new DelegateCommand<object>(RemoveCommand_Execute, RemoveCommand_CanExecute, "Save");
    }

    void RemoveCommand_Execute(object arg)
    {
        Model.Powers.Clear();
        MessageBox.Show(string.Format("{0} character powers removed.", Model.Name));
    }

    bool RemoveCommand_CanExecute(object arg)
    {
        return Model.Name != string.Empty;
    }
}

型号代码:

public class Character : ObjectBase
{
    string _Name = string.Empty;
    ObservableCollection<string> _Powers = new ObservableCollection<string>();

    public string Name
    {
        get { return _Name; }
        set
        {
            if (_Name == value)
                return;

            _Name = value;
            OnPropertyChanged("Name");
        }
    }

    public ObservableCollection<string> Powers
    {
        get { return _Powers; }
    }

    public static Character Create()
    {
        Character hero = new Character()
        {
            Name = "Superman",
        };

        hero.Powers.Add("Flight");
        hero.Powers.Add("Strength");
        hero.Powers.Add("X-Ray Vision");

        return hero;
    }
}

框架代码:

public class DelegateCommand<T> : ICommand
{
    public DelegateCommand(Action<T> execute) : this(execute, null) { }

    public DelegateCommand(Action<T> execute, Predicate<T> canExecute) : this(execute, canExecute, "") { }

    public DelegateCommand(Action<T> execute, Predicate<T> canExecute, string label)
    {
        _Execute = execute;
        _CanExecute = canExecute;

        Label = label;
    }

    readonly Action<T> _Execute = null;
    readonly Predicate<T> _CanExecute = null;

    public string Label { get; set; }

    public void Execute(object parameter)
    {
        _Execute((T)parameter);
    }

    public bool CanExecute(object parameter)
    {
        return _CanExecute == null ? true : _CanExecute((T)parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add
        {
            if (_CanExecute != null)
                CommandManager.RequerySuggested += value;
        }
        remove
        {
            if (_CanExecute != null)
                CommandManager.RequerySuggested -= value;
        }
    }
}

public abstract class ObjectBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected internal void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

感谢您的帮助

4

1 回答 1

1

ListItem 的 DataContext 是它所绑定的项目,而不是您要查找的项目。您正在寻找 UserControl 的 DataContext 并得到它,您需要使用ElementName显式引用 UserControl或使用RelativeSource绑定来探索可视化树。RelativeSource 可能是最好的解决方案,因为它引用了控件本身,您需要在您正在寻找 DataContext 上的 RemoveCommand 成员的绑定路径中指定 - 类似于Path=DataContext.RemoveCommand. 请参阅下面的完整示例。

XAML:

<Grid DataContext="{Binding}"> <!-- Set the binding for the DataContext of the control and all of its children -->
    <ListView ItemsSource="{Binding Path=Model.Powers}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <!-- Use RelativeSource to access the Grid control and then get its DataContext -->
                <Button Command="{Binding Path=DataContext.RemoveCommand, RelativeSource={RelativeSource AncestorType=Grid}}">
                    <Border HorizontalAlignment="Center" VerticalAlignment="Center" >
                        <Image Width="50" Height="50" Source="/WpfApplication2;component/Images/Jellyfish.jpg"/>
                    </Border>
                </Button>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>
于 2012-04-29T04:44:11.797 回答