背景:我正在尝试根据文本框是否选择了文本来启用和禁用命令。
根据我的研究,我需要使用事件触发器。这个问题所涉及的InvokeCommandAction或由于某种原因在我的系统上不存在的InvokeMethodAction。
问题:我已经按照以下步骤设置了该程序。它运行,命令启动,但参数始终为零。
<Window x:Class="LogWpfApp.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:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:local="clr-namespace:LogWpfApp"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" Content="Copy" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="75"
Command="{Binding CmdCopy}" CommandTarget="{Binding ElementName=textBoxNote}" CommandParameter="{Binding ElementName=textBoxNote}"/>
<Button Grid.Row="0" Grid.Column="1" Content="Paste" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="75"
/>
<TextBox x:Name="textBoxNote" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,0,0" TextWrapping="Wrap"
Text="{Binding Note}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding CmdSelectionLengthChanged}" CommandParameter="{Binding ElementName=textBoxNote, Path=SelectionLength}" />
<i:InvokeCommandAction Command="{Binding CmdSelectionStartChanged}" CommandParameter="{Binding ElementName=textBoxNote, Path=SelectionStart}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Content="{Binding Clipboard}"/>
</Grid>
</Window>
这是ViewModel:
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private RelayCommand<TextBox, TextBox> cmdCopy;
private RelayCommand<object, object> cmdPaste = new RelayCommand<object, object>(foo => { }, (tb) => { return true; });
private RelayCommand<int, int> cmdSelectionLengthChanged;
private RelayCommand<int, int> cmdSelectionStartChanged;
private String note = "This is some default initial text";
private String clippboard = "";
private int selectionLength = 0;
private int selectionStart = 0;
public ViewModel()
{
cmdCopy = new RelayCommand<TextBox, TextBox>(
tb => { clippboard = tb.SelectedText; },
tb => { return SelectionLength > 0; /* tb != null && tb.SelectionLength > 0;*/ }
);
cmdSelectionLengthChanged = new RelayCommand<int, int>(
length => {
Console.WriteLine("New SelectionLength {0}", length);
SelectionLength = length; cmdCopy.FireCanExecuteChanged(); },
foo => { return true; }
);
cmdSelectionStartChanged = new RelayCommand<int, int>(
start => {
Console.WriteLine("New SelectionStart {0}", start);
selectionStart = start; },
foo => { return true; }
);
}
public RelayCommand<TextBox, TextBox> CmdCopy => cmdCopy;
public RelayCommand<object, object> CmdPaste => cmdPaste;
public RelayCommand<int, int> CmdSelectionLengthChanged => cmdSelectionLengthChanged;
public RelayCommand<int, int> CmdSelectionStartChanged => cmdSelectionStartChanged;
public String Note
{
get { return note; }
set
{
if (this.note != value)
{
this.note = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Note)));
}
}
}
public String Clipboard
{
get { return clippboard; }
private set
{
if (clippboard != value)
{
clippboard = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Clipboard)));
}
}
}
public int SelectionLength
{
get { return selectionLength; }
set
{
if (selectionLength != value)
{
selectionLength = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectionLength)));
}
}
}
}
答案 0 :(得分:0)
SelectionLength
和SelectionStart
都不是在设置通知时会发出通知的依赖项属性。这意味着命令参数的值将始终具有0
的初始值。
如果您绑定到TextBox
本身:
<i:InvokeCommandAction Command="{Binding CmdSelectionLengthChanged}" CommandParameter="{Binding ElementName=textBoxNote}" />
...您将可以通过在Execute
方法中显式查询属性来检索值:
cmdSelectionLengthChanged = new DelegateCommand<TextBox, TextBox>(
textBox => {
Debug.WriteLine("New SelectionLength {0}", textBox.SelectionLength);
},
foo => { return true; }
);