xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
<TextBox x:Name="textbox" Grid.Row="1" Margin="5" TextWrapping="Wrap">
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding MouseDownCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=TextBox}}">
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
元素/属性 | 描述 |
---|---|
TextBox | Name="textbox", Grid.Row=1, Margin=5, TextWrapping=Wrap |
子元素 | <i:Interaction.Triggers> (事件触发器容器) |
i:Interaction.Triggers | 包含一个EventTrigger |
i:EventTrigger | EventName="PreviewMouseDown"(触发时机为鼠标按下前) |
i:InvokeCommandAction | 命令绑定动作 |
Command | {Binding MouseDownCommand} (绑定到ViewModel的ICommand对象) |
CommandParameter | {Binding RelativeSource={...}} (绑定到TextBox自身,通过祖先查找) |
graph TD
A[TextBox] --> B[属性]
A --> C[子元素: Interaction.Triggers]
B --> B1[Name=textbox]
B --> B2[Grid.Row=1]
B --> B3[Margin=5]
B --> B4[TextWrapping=Wrap]
C --> C1[EventTrigger]
C1 --> C1a[EventName=PreviewMouseDown]
C1 --> C1b[InvokeCommandAction]
C1b --> C1b1[Command绑定]
C1b1 --> VM[ViewModel.MouseDownCommand]
C1b --> C1b2[CommandParameter]
C1b2 --> Self[TextBox自身引用]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace wpfrunrun
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//MessageBox.Show("HelloWorld");
}
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("我是ALT+S");
}
private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void OpenCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void OpenCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
var openFileDialog = new Microsoft.Win32.OpenFileDialog()
{
Filter = "文本文档(.txt)|*.txt",
Multiselect = true,
};
var result = openFileDialog.ShowDialog();
if(result.Value)
{
txtBox.Text = File.ReadAllText(openFileDialog.FileName);
}
}
private void CutCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = txtBox != null && txtBox.SelectionLength > 0;
}
private void CutCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
txtBox.Cut();
}
private void PasteCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = Clipboard.ContainsImage();
}
private void PasteCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
txtBox.Paste();
}
private void SaveCommandCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = txtBox != null && txtBox.Text.Length > 0;
}
private void SaveCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
var saveFileDialog = new Microsoft.Win32.SaveFileDialog()
{
Filter = "文本文档(.txt)|*.txt"
};
if(saveFileDialog.ShowDialog() == true)
{
File.WriteAllText(saveFileDialog.FileName, txtBox.Text);
}
}
}
//public class RelayCommand : ICommand
//{
// private Action action;
// public RelayCommand(Action action)
// {
// this.action = action;
// }
// public event EventHandler CanExecuteChanged;
// public bool CanExecute(object parameter)
// {
// return true;
// }
// public void Execute(object parameter)
// {
// action?.Invoke();
// }
//}
public class RelayCommand : ICommand
{
private Action action;
private Action<object> objectAction;
public RelayCommand(Action action)
{
this.action = action;
}
public RelayCommand(Action<object> objectAction)
{
this.objectAction = objectAction;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
action?.Invoke();
objectAction?.Invoke(parameter);
}
}
public class MainViewModel : ObservableObject
{
public RelayCommand OpenCommand { get; set; } = new RelayCommand(() =>
{
MessageBox.Show("HelloWorld");
});
public RelayCommand OpenParamCommand { get; set; } = new RelayCommand((param) =>
{
MessageBox.Show(param.ToString());
});
public RelayCommand OpenTParamCommand { get; set; } = new RelayCommand ((t) =>
{
MessageBox.Show(t.ToString());
});
public RelayCommand<TextBox> MouseDownCommand { get; set; } = new RelayCommand<TextBox>((txtBox) =>
{
txtBox.Text += DateTime.Now + "宁点击泪" + "\r";
});
}
public class RelayCommand<T> : ICommand
{
public RelayCommand(Action<T> action)
{
Action = action;
}
public event EventHandler CanExecuteChanged;
public Action<T> Action { get; }
public Action<object> Value { get; }
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
Action?.Invoke((T)parameter);
}
}
public class ObservableObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}