交互触发器似乎没有触发

时间:2015-03-14 16:50:29

标签: wpf vb.net xaml

我有一个用户控件,我已经在底层视图模型中处理各种控件的事件进行了一些实验。在许多情况下,我发现使用一些基本的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>

由于

2 个答案:

答案 0 :(得分:1)

互动要求。触发程序起作用:

  1. 添加对“ System.Windows.Interactivity”的引用
    a)这是一种方法。 https://stackoverflow.com/a/52110697/6010880
  2. 将此属性添加到XAML。
    b)xmlns:i =“ http://schemas.microsoft.com/expression/2010/interactivity”

    enter image description here

    这是完整的解决方案,您可以从新项目尝试。只需复制并粘贴以下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     
{         
私有只读谓词 _canExecute;         
私有只读操作 _execute;

    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)

它对我有用......很少有可能要检查的事情:

  1. 您正在使用System.Windows.Interactivity吗?
  2. 您确定您的命令是在更改通知属性,还是在InitializeComponent()之前设置?
  3. 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);
            }
        }
    }