WPF ItemsControl 无法绑定命令
Posted
技术标签:
【中文标题】WPF ItemsControl 无法绑定命令【英文标题】:WPF ItemsControl can't bind Command 【发布时间】:2021-11-05 07:13:39 【问题描述】:我是 wpf 的新手,我知道这个问题已经在其他时候被问过,我尝试实施一些我找到的解决方案。但它不起作用。我做错了什么,但我看不到它是什么。 我创建了一个新的简单应用程序来测试这个问题。
namespace WpfApp3
public class MyElement
public string Text get; set;
public MyElement(string t)
Text = t;
public class MyCommand : ICommand
public bool CanExecute(object parameter)
return true;
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
_handler(parameter);
private Action<object> _handler;
public MyCommand(Action<object> handler) _handler = handler;
public class MyItemsControlViewModel
ObservableCollection<MyElement> _items;
public ObservableCollection<MyElement> MyElementItems get return _items; set _items = value; RaisePropertyChanged("MyElementItems");
ObservableCollection<MyElement> _temporayList;
private ICommand _itemClicked;
public ICommand ItemClicked get return _itemClicked;
public MyItemsControlViewModel()
_items = new ObservableCollection<MyElement>();
_temporayList = new ObservableCollection<MyElement>();
_itemClicked = new MyCommand(OnItemSelected);
AddItem("Element 1");
AddItem("Element 2");
AddItem("Element 3");
UpdateList();
public void UpdateList()
MyElementItems = _temporayList;
public void AddItem(string t)
MyElement item = new MyElement(t);
_temporayList.Add(item);
public void OnItemSelected(object param)
Debug.WriteLine("Executed!");
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string propertyName)
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
XAML
<UserControl x:Class="WpfApp3.MyUserControl"
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:local="clr-namespace:WpfApp3"
mc:Ignorable="d"
d:DesignHeight="1080" d:DesignWidth="570"
x:Name="myCustomControl">
<Grid >
<Button x:Name="btnOutsideItemsControl" Width="100" Height="100 " VerticalAlignment="Top" Command="Binding ItemClicked" />
<ItemsControl
x:Name="listItems"
ScrollViewer.PanningMode="None"
IsEnabled="False"
Background = "Transparent"
HorizontalAlignment="Center"
ItemsSource="Binding MyElementItems" Margin="0,152,0,0" Width="549">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Left" Margin="50,0,0,0"
Background="Transparent" Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button
Content="Binding Text"
Command="Binding ElementName=listItems, Path=DataContext.ItemClicked"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>
该组件在 MainWindow.xaml 中使用。
namespace WpfApp3
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
private MyItemsControlViewModel _myViewModel;
public MyItemsControlViewModel MyViewModel get return _myViewModel;
public MainWindow()
_myViewModel = new MyItemsControlViewModel();
InitializeComponent();
myCustomControl.DataContext = MyViewModel;
XAML
<Window x:Class="WpfApp3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp3"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<local:MyUserControl x:Name="myCustomControl"/>
</Grid>
</Window>
当我运行应用程序时,我可以正确地看到包含正确文本的 3 项列表。 但是,如果我单击列表中的一个按钮,我将看不到 Debug.WriteLine("Executed!");
的输出但是,如果我单击 ItemsControl 之外的按钮 btnOutsideItemsControl,它就可以工作。我可以看到 Debug.WriteLine("Executed!"); 的输出 所以我认为命令的定义也是正确的。
要正确绑定 ItemsControl 内 Button 的 Command 属性,我试试这个
<Button Command="Binding ElementName=listItems, Path=DataContext.ItemClicked">
还有这个
<Button Command="Binding DataContext.ItemClicked, RelativeSource=RelativeSource Mode=FindAncestor,AncestorType=ItemsControl">
但它不起作用。
请帮忙!
【问题讨论】:
这令人困惑。视图模型有一个空的 OnItemSelected 方法,该方法应该由 ItemClicked 执行,但您正在谈论的是 OnMyItemSelected 方法。哪里是?尝试将您的代码减少到最小的可重现示例。删除与问题无关的内容。 请注意,UpdateList()
不会通知 UI,因为您设置了支持字段,而不是属性 MyElementItems
。
感谢@Clemens 的回复和建议。我改变了问题。我创建了一个新的应用程序 WpfApp3 并添加了查看我的问题所需的最少代码。如果仍然感到困惑,请告诉我。谢谢!
【参考方案1】:
一旦我告诉你,你会踢自己的。
您的问题是您在ItemsControl
上设置了IsEnabled="False"
。删除它,宇宙就会一切顺利。
【讨论】:
是的,我绝对想踢自己!我不知道我怎么没看到!非常感谢以上是关于WPF ItemsControl 无法绑定命令的主要内容,如果未能解决你的问题,请参考以下文章
ItemsControl 中 DataTemplate 中的 WPF UserControl - 如何绑定到 ItemsSource 的父级
WPF: WrapPanel 容器的模板数据绑定(ItemsControl)
在WPF中的UserControl中的ItemsControl中绑定问题