项目控件中的 ICommand 按钮绑定
ICommand Button binding in Itemcontrol
有 xaml.cs 个文件,其中包含我的 ViewModel 的 ObservableCollection。我现在已经实现了一个绑定到按钮单击的命令,它在视图模型中调用我的函数。问题是我没有在我的按钮点击功能中得到我列表中的项目
xaml
<ItemsControl ItemsSource="{Binding ConditionList}" AlternationCount="{Binding ConditionList.Count}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Button Content="{Binding}" Command="{Binding DataContext.DeleteCondition,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding}" />
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
请注意我的按钮在 ItemControl 中
虚拟机
private void DoDeleteCondition(object parameter)
{
// if (parameter != null)
// ...
}
public ICommand DeleteCondition
{
get
{
if (_DeleteCondition == null)
_DeleteCondition = new RelayCommand(o => DoDeleteCondition(o));
return _DeleteCondition;
}
}
您需要创建一个 RelayCommand<T>
,其中 T 是 ConditionList
中的项目。然后你会在execute方法中得到你的参数。
我感觉你的装订有点反了。
在你的 ItemsControl 中你想拥有:
- 来自您的 collection 的项目以及当您单击单个项目时将执行的一个命令
- 或您希望对其他地方的单个项目执行的可能命令列表(意味着 collection 显示在某些 parent 元素上,因此您可以绑定到单个项目不知何故)?
- ... 或者您可能为 collection 中的每个项目定义了一个单独的命令...? (那么,你的collection中的元素是如何实现的?)
取决于您的回答:
1:
<ItemsControl ItemsSource="{Binding Path=MyObservableCollection}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Button Content="{Binding}"
Command="{Binding Path=DataContext.DeleteCondition, RelativeSource={RelativeSource AncestorType=AncestorWithYourViewModelAsDataContext}}"
CommandParameter="{Binding}" />
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
2:
<ItemsControl ItemsSource="{Binding Path=ConditionList}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Button Content="{Binding}"
Command="{Binding Path=MyConditionalCommand}"
CommandParameter="{BindingToTheElementOfYourCllectionThatYouWantToActUpon}" />
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
ViewModel 中的示例实现:
private List<ConditionalCommand> _ConditionList;
public List<ConditionalCommand> ConditionList
{
get { return _ConditionList; }
set
{
if (_ConditionList != value)
{
_ConditionList = value;
OnPropertyChanged("ConditionList");
}
}
}
...
class ConditionalCommand
{
public ICommand MyConditionalCommand { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
...
this.ConditionList = new List<ConditionalCommand>();
this.ConditionList.Add(new ConditionalCommand{ MyConditionalCommand = DeleteCondition , Name="Delete"});
this.ConditionList.Add(new ConditionalCommand{ MyConditionalCommand = DeleteSpecial, Name="Delete special" });
.....
private void DoDeleteCondition(object parameter)
{
// if (parameter != null)
// ...
}
public ICommand DeleteCondition
{
get
{
if (_DeleteCondition == null)
_DeleteCondition = new RelayCommand(o => DoDeleteCondition(o));
return _DeleteCondition;
}
}
// DeleteSpecial implemented in similar manner...
有 xaml.cs 个文件,其中包含我的 ViewModel 的 ObservableCollection。我现在已经实现了一个绑定到按钮单击的命令,它在视图模型中调用我的函数。问题是我没有在我的按钮点击功能中得到我列表中的项目
xaml
<ItemsControl ItemsSource="{Binding ConditionList}" AlternationCount="{Binding ConditionList.Count}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Button Content="{Binding}" Command="{Binding DataContext.DeleteCondition,
RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding}" />
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
请注意我的按钮在 ItemControl 中
虚拟机
private void DoDeleteCondition(object parameter)
{
// if (parameter != null)
// ...
}
public ICommand DeleteCondition
{
get
{
if (_DeleteCondition == null)
_DeleteCondition = new RelayCommand(o => DoDeleteCondition(o));
return _DeleteCondition;
}
}
您需要创建一个 RelayCommand<T>
,其中 T 是 ConditionList
中的项目。然后你会在execute方法中得到你的参数。
我感觉你的装订有点反了。
在你的 ItemsControl 中你想拥有:
- 来自您的 collection 的项目以及当您单击单个项目时将执行的一个命令
- 或您希望对其他地方的单个项目执行的可能命令列表(意味着 collection 显示在某些 parent 元素上,因此您可以绑定到单个项目不知何故)?
- ... 或者您可能为 collection 中的每个项目定义了一个单独的命令...? (那么,你的collection中的元素是如何实现的?)
取决于您的回答:
1:
<ItemsControl ItemsSource="{Binding Path=MyObservableCollection}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Button Content="{Binding}"
Command="{Binding Path=DataContext.DeleteCondition, RelativeSource={RelativeSource AncestorType=AncestorWithYourViewModelAsDataContext}}"
CommandParameter="{Binding}" />
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
2:
<ItemsControl ItemsSource="{Binding Path=ConditionList}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Button Content="{Binding}"
Command="{Binding Path=MyConditionalCommand}"
CommandParameter="{BindingToTheElementOfYourCllectionThatYouWantToActUpon}" />
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
ViewModel 中的示例实现:
private List<ConditionalCommand> _ConditionList;
public List<ConditionalCommand> ConditionList
{
get { return _ConditionList; }
set
{
if (_ConditionList != value)
{
_ConditionList = value;
OnPropertyChanged("ConditionList");
}
}
}
...
class ConditionalCommand
{
public ICommand MyConditionalCommand { get; set; }
public string Name { get; set; }
public override string ToString()
{
return Name;
}
}
...
this.ConditionList = new List<ConditionalCommand>();
this.ConditionList.Add(new ConditionalCommand{ MyConditionalCommand = DeleteCondition , Name="Delete"});
this.ConditionList.Add(new ConditionalCommand{ MyConditionalCommand = DeleteSpecial, Name="Delete special" });
.....
private void DoDeleteCondition(object parameter)
{
// if (parameter != null)
// ...
}
public ICommand DeleteCondition
{
get
{
if (_DeleteCondition == null)
_DeleteCondition = new RelayCommand(o => DoDeleteCondition(o));
return _DeleteCondition;
}
}
// DeleteSpecial implemented in similar manner...