ダミーのWPFアプリケーション(MVVM指向)を入手したとしましょう。メインウィンドウには、作成したカスタムリストが含まれ、リストにはカスタムアイテムが含まれています。アイテムには画像ボタンがあり、ボタンコマンドをビューモデルで取得したコマンドにします。ビューモデルはメインウィンドウにバインドされています。どうすればいいですか?
ダミープロジェクトを添付しました(ここからダウンロード: http://www.2shared.com/file/qmO3E5rx/NestedCommand.html またはここ:http : //www.multiupload.nl/KCFLSKAIH0)、
ただし、ダウンロードしたくない場合、コードは次のようになります。
MainWindow 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>
ViewModelコード:
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));
}
}
助けてくれてありがとう