Справочная информация. Я пытаюсь включить и отключить команду в зависимости от того, выделено ли текстовое поле или нет.
Согласно моим исследованиям, мне нужно использовать триггеры событий. Либо действие 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)));
}
}
}
}