无法将 DataTemplate 中的按钮绑定到 RelayCommand
Trouble binding buttons in a DataTemplate to a RelayCommand
我有一个显示动态按钮列表(显示为文本)的视图。用户已经期望文本是“可选择的”。但这不是重点。
我正在尝试将按钮绑定到 RelayCommand,但是当我测试时,单击一行文本不会导致执行绑定的命令。我不确定我错过了什么。这是我第一次尝试这样的事情,使用带有 DataTemplate 的 ItemsControl。我错过了什么?这是视图 xaml:
<Window x:Class="MyCode.Correction.CorrectionView"
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:ls="clr-namespace:MyCode.Correction"
DataContext="{Binding Source={StaticResource Locator}, Path=CorrectionViewModel, UpdateSourceTrigger=PropertyChanged}"
mc:Ignorable="d"
Width="270"
Height="300"
ResizeMode="NoResize"
Title="Correction menu"
Topmost="True"
WindowStartupLocation="CenterOwner"
Icon="/MyApp;component/Images/cc.ico"
AutomationProperties.AutomationId="CorrectionWindow">
<Grid Margin="0,10,-6,9" RenderTransformOrigin="0.264,0.344">
<Grid.RowDefinitions>
<RowDefinition Height="114*" />
</Grid.RowDefinitions>
<ItemsControl ItemsSource="{Binding CorrectionOptions}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}"
Command="{Binding CorrectionCommand, Mode=OneTime}"
CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}"
Margin="20,5,0,0"
FontSize="15">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter />
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
这是视图模型:
namespace MyCode.Correction
{
public class CorrectionViewModel : DialogViewModelBase
{
private readonly IDialogService _dialogService;
private readonly ILogger Logger;
public CorrectionViewModel(IDialogService dialogService)
{
Logger = LoggerFactory.GetLoggerInstance(typeof(CorrectionViewModel));
CorrectionCommand = new RelayCommand<object>((s) => OnCorrectionClicked(s));
_dialogService = dialogService;
}
public RelayCommand<object> CorrectionCommand { get; set; }
private ObservableCollection<string> _correctionOptions;
public ObservableCollection<string> CorrectionOptions
{
get
{
return _correctionOptions;
}
set
{
Set(() => CorrectionOptions, ref _correctionOptions, value);
}
}
private void OnCorrectionClicked(object selectedCorrection)
{
UserDialogResult = (string)selectedCorrection;
CloseAction();
}
}
}
你的命令和参数绑定错误。
Command
绑定必须指向父 ItemsControl
的数据上下文,即包含 CorrectionCommand
的 CorrectionViewModel
。这是使用 RelativeSource
.
完成的
CommandParameter
是当前数据上下文本身(点击的更正选项string
)。 TemplatedParent
as RelativeSource
仅用于控件模板,不适用于数据模板。
它应该像这样工作。
<ItemsControl ItemsSource="{Binding CorrectionOptions}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}"
Command="{Binding DataContext.CorrectionCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
CommandParameter="{Binding}"
Margin="20,5,0,0"
FontSize="15">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter />
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我有一个显示动态按钮列表(显示为文本)的视图。用户已经期望文本是“可选择的”。但这不是重点。
我正在尝试将按钮绑定到 RelayCommand,但是当我测试时,单击一行文本不会导致执行绑定的命令。我不确定我错过了什么。这是我第一次尝试这样的事情,使用带有 DataTemplate 的 ItemsControl。我错过了什么?这是视图 xaml:
<Window x:Class="MyCode.Correction.CorrectionView"
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:ls="clr-namespace:MyCode.Correction"
DataContext="{Binding Source={StaticResource Locator}, Path=CorrectionViewModel, UpdateSourceTrigger=PropertyChanged}"
mc:Ignorable="d"
Width="270"
Height="300"
ResizeMode="NoResize"
Title="Correction menu"
Topmost="True"
WindowStartupLocation="CenterOwner"
Icon="/MyApp;component/Images/cc.ico"
AutomationProperties.AutomationId="CorrectionWindow">
<Grid Margin="0,10,-6,9" RenderTransformOrigin="0.264,0.344">
<Grid.RowDefinitions>
<RowDefinition Height="114*" />
</Grid.RowDefinitions>
<ItemsControl ItemsSource="{Binding CorrectionOptions}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}"
Command="{Binding CorrectionCommand, Mode=OneTime}"
CommandParameter="{Binding RelativeSource={RelativeSource TemplatedParent}}"
Margin="20,5,0,0"
FontSize="15">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter />
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
这是视图模型:
namespace MyCode.Correction
{
public class CorrectionViewModel : DialogViewModelBase
{
private readonly IDialogService _dialogService;
private readonly ILogger Logger;
public CorrectionViewModel(IDialogService dialogService)
{
Logger = LoggerFactory.GetLoggerInstance(typeof(CorrectionViewModel));
CorrectionCommand = new RelayCommand<object>((s) => OnCorrectionClicked(s));
_dialogService = dialogService;
}
public RelayCommand<object> CorrectionCommand { get; set; }
private ObservableCollection<string> _correctionOptions;
public ObservableCollection<string> CorrectionOptions
{
get
{
return _correctionOptions;
}
set
{
Set(() => CorrectionOptions, ref _correctionOptions, value);
}
}
private void OnCorrectionClicked(object selectedCorrection)
{
UserDialogResult = (string)selectedCorrection;
CloseAction();
}
}
}
你的命令和参数绑定错误。
完成的Command
绑定必须指向父ItemsControl
的数据上下文,即包含CorrectionCommand
的CorrectionViewModel
。这是使用RelativeSource
.CommandParameter
是当前数据上下文本身(点击的更正选项string
)。TemplatedParent
asRelativeSource
仅用于控件模板,不适用于数据模板。
它应该像这样工作。
<ItemsControl ItemsSource="{Binding CorrectionOptions}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding}"
Command="{Binding DataContext.CorrectionCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"
CommandParameter="{Binding}"
Margin="20,5,0,0"
FontSize="15">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<ContentPresenter />
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>