我有一个用户控件,我已经在底层视图模型中处理各种控件的事件进行了一些实验。在许多情况下,我发现使用一些基本的xaml就像下面的位一样。
<i:Interaction.Triggers>
<i:EventTrigger EventName="Event to be handled">
<i:InvokeCommandAction Command="{Binding Path= I Command handling event}" />
</i:EventTrigger>
</i:Interaction.Triggers>
但是我一直在尝试使用我的xaml中定义的文本框,如下所示:
<TextBox x:Name="TxtInvNumber" Margin="5" Grid.Column="1" Width="80" Text="{Binding Path=InvoiceNumber}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding Path=InvoiceNumberChangedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
当像这样完成并且在InvoiceNumberChangedCommand上设置断点时没有任何反应,但是如果我在视图后面的代码中的TextChanged处理程序中放置一个简单的消息框,则每次都会触发它。
任何人都可以解释这是否是特定于文本框的内容,还是以这种方式使用交互来处理事件并不总是有效?
顺便说一下,我想知道这是否与文本框文本属性绑定到实现propertychanged的底层属性这一事实有关,所以我尝试了LostFocus事件,但结果仍然相同。 / p>
由于
答案 0 :(得分:1)
互动要求。触发程序起作用:
将此属性添加到XAML。
b)xmlns:i =“ http://schemas.microsoft.com/expression/2010/interactivity”
这是完整的解决方案,您可以从新项目尝试。只需复制并粘贴以下4个文件:
1。 MainWindow.xaml
2。 MainWindow.xaml.cs
3。主视图模型
4。 DelegateCommand.cs
XAML
隐藏代码(MainWindow.xaml.cs)
using System.Windows;
命名空间WpfApp1
{
公共局部类MainWindow:Window
{
私有只读MainViewModel _main = new MainViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = _main; //<-- It does not need to be before InitializeComponent()
}
}
}
MainViewModel.cs
using System.Windows.Input;
命名空间WpfApp1 { 公共类MainViewModel { 受保护的ICommand _windowsLoadedVm;
public ICommand WindowsLoadedVm
{
get
{
if (_windowsLoadedVm == null)
{
_windowsLoadedVm = new DelegateCommand(WindowsLoadedHandler);
}
return _windowsLoadedVm;
}
}
public void WindowsLoadedHandler(object parameter)
{
//Do your thang!
}
}
}
DelegateCommand.cs
using System;
使用System.Windows.Input;
命名空间WpfApp1
{
公共类DelegateCommand:ICommand
{
私有只读谓词
public event EventHandler CanExecuteChanged;
public DelegateCommand(Action<object> execute)
: this(execute, null)
{
}
public DelegateCommand(Action<object> execute,
Predicate<object> canExecute)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
if (_canExecute == null)
{
return true;
}
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
}
答案 1 :(得分:0)
它对我有用......很少有可能要检查的事情:
View.cs
public partial class InteractionTriggerNotFiring : Window
{
public InteractionTriggerNotFiring()
{
DataContext = new SO29051551VM();
InitializeComponent();
}
}
View.xaml
<Window x:Class="WpfApplication1.InteractionTriggerNotFiring"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Title="InteractionTriggerNotFiring" Height="300" Width="300">
<Grid>
<TextBox x:Name="TxtInvNumber" Margin="5" Grid.Column="1" Width="80" Text="{Binding Path=InvoiceNumber}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding Path=InvoiceNumberChangedCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</Grid>
</Window>
查看模型
public class SO29051551VM : ViewModelBase
{
private RelayCommand _invoiceNumberChangedCommand;
public SO29051551VM()
{
InvoiceNumberChangedCommand = new RelayCommand(() =>
{
Console.WriteLine("TEst");
});
}
public RelayCommand InvoiceNumberChangedCommand
{
get { return _invoiceNumberChangedCommand; }
set
{
if (_invoiceNumberChangedCommand == value) return;
_invoiceNumberChangedCommand = value;
RaisePropertyChanged(() => InvoiceNumberChangedCommand);
}
}
}