2012-04-27 51 views
0

可以說我有一個虛擬的WPF應用程序(面向MVVM)。 我的主窗口包含我創建的自定義列表,並且列表包含自定義項目。 該項目有一個圖像按鈕,我希望按鈕命令是我在視圖模型中得到的命令。視圖模型綁定到主窗口。 我該怎麼做?無法訪問嵌套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> 

主窗口中的代碼隱藏:

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

感謝您的幫助

+0

請人! – Lironess 2012-04-28 17:37:21

回答

1

在DataContext的列表項是,它必然是不是你的項目正在尋找。您正在查找UserControl的DataContext並獲得您需要使用ElementName明確引用UserControl或使用RelativeSource綁定來瀏覽可視化樹。 RelativeSource可能是最好的解決方案,因爲它引用了控件本身,所以您需要在綁定的Path中指定要查找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> 
+0

謝謝,解決了! – Lironess 2012-05-06 13:00:09

+1

@Lironess如果這回答你的問題,請將其標記爲已接受。 – 2012-05-06 13:39:06