混合EventTrigger“点击"使用常规命令时不会触发 [英] Blend EventTrigger "Click" doesn't fire, while using regular commands works

查看:85
本文介绍了混合EventTrigger“点击"使用常规命令时不会触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我在其中应用ColumnHeaderStyle的DataGrid中.样式又包含包含按钮的模板.
当用户单击按钮时,我希望能够在窗口级别(在DataGrid上方)捕获它.

当使用常规"命令(ButtonBase.Click)时,它可以工作,但是当我使用Blend时,它就不行.

请帮忙.

Hi all,

I have a DataGrid where I apply the ColumnHeaderStyle. The style in turn contains template that contains a button.
When user click on the button I want to be able to catch it at the window level (above the DataGrid).

When using "regular" command (ButtonBase.Click) it works, but when I''m using blend it doesn''t.

Please help.

<Window x:Class="Tac.MainWindow"

          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

             xmlns:tac="clr-namespace:Tac"

             mc:Ignorable="d"

             d:DesignHeight="300" d:DesignWidth="300" ButtonBase.Click="dataGrid1_Click">

    <!--This won't fire. But ButtonBase.Click works just fine !?-->
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <tac:ExecuteCommandAction Command="{Binding FilterLoadedCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Generic.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <DataGrid x:Name="dataGrid1" IsReadOnly="True" SelectionMode="Extended"

            ColumnHeaderStyle="{StaticResource DataGridHeaderFilterControl}"

            ItemsSource="{Binding ItemsSource, Mode=OneWay}">

    </DataGrid>
</Window>


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using System.Data;
using System.Collections;

namespace Tac
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        DataTable dt = new DataTable();

        public RelayCommand<object> FilterLoadedCommand { get; private set; }

        public MainWindow()
        {
            InitializeComponent();

            FilterLoadedCommand = new RelayCommand<object>(param => FilterLoadedChanged());

            DataContext = this;

            dt.Columns.Add("Vendor", typeof(string));

            for (int i = 0; i < 20; i++)
            {
                dt.Rows.Add(Convert.ToChar(i + 65));
            }

            this.dataGrid1.ItemsSource = new DataView(dt);
        }

        // Never arrives here !!
        void FilterLoadedChanged()
        {

        }

        // This works
        private void dataGrid1_Click(object sender, RoutedEventArgs e)
        {

        }
    }
}


<ResourceDictionary

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"

    xmlns:s="clr-namespace:System;assembly=mscorlib"

    xmlns:filter="clr-namespace:FilterLibrary.Filter"

    xmlns:local="clr-namespace:FilterLibrary">

    <Style x:Key="DataGridHeaderFilterControl" TargetType="{x:Type DataGridColumnHeader}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                    <Button Height="25" Content="Click"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

推荐答案

经过大量调查,我发现了以下内容.
如果从Window.Resources
中的控件触发了事件 无论如何,它都不会被混合物抓住.
使其起作用的唯一选择是在MainWindow.cs中注册此事件.

这是代码.如果单击按钮,则永远不会触发该事件

After a lot of investigation I have found the following.
If event is fired from the control located in the Window.Resources
it won''t be caught by the blend no matter what.
The only option to make it work is to register this event in the MainWindow.cs .

Here is the code. The event is never fired if clicked on the button

<pre lang="xml"><Window x:Class="Tac.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
             xmlns:tac="clr-namespace:Tac"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300" >

    <i:Interaction.Triggers>
        <!--This never works no matter what-->
        <i:EventTrigger EventName="FilterLoaded" SourceName="MyBtn">
            <tac:ExecuteCommandAction Command="{Binding FilterLoadedCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>

    <Window.Resources>
        <Style x:Key="DataGridHeaderFilterControl" TargetType="{x:Type DataGridColumnHeader}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
                        <tac:MyButton Height="25" Content="Click" x:Name="MyBtn"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <DataGrid x:Name="dataGrid1" IsReadOnly="True" SelectionMode="Extended"
            ColumnHeaderStyle="{StaticResource DataGridHeaderFilterControl}"
            ItemsSource="{Binding ItemsSource, Mode=OneWay}">
    </DataGrid>
</Window>







using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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;
using System.Data;
using System.Collections;
namespace Tac
{
   
    public partial class MainWindow : Window
    {
        DataTable dt = new DataTable();
        public RelayCommand<object> FilterLoadedCommand { get; private set; }
        public MainWindow()
        {
            InitializeComponent();
            FilterLoadedCommand = new RelayCommand<object>(param => FilterLoadedChanged());
            DataContext = this;
            dt.Columns.Add("Vendor", typeof(string));
            for (int i = 0; i < 5; i++)
            {
                dt.Rows.Add(Convert.ToChar(i + 65));
            }
            this.dataGrid1.ItemsSource = new DataView(dt);
        }
        // Never arrives here if the event is fired from the template !!
        void FilterLoadedChanged()
        {
        }
    }
}





<pre lang="cs">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Collections;

namespace Tac
{
    class MyButton : Button
    {
        public static readonly RoutedEvent FilterLoadedEvent = EventManager.RegisterRoutedEvent(
          "FilterLoaded", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButton));

        public event RoutedEventHandler FilterLoaded
        {
            add { AddHandler(FilterLoadedEvent, value); }
            remove { RemoveHandler(FilterLoadedEvent, value); }
        }

        protected override void OnClick()
        {
            base.OnClick();

            RaiseEvent(new RoutedEventArgs(MyButton.FilterLoadedEvent));
        }
    }
}




现在,如果要在MainWindow中添加以下代码




Now if I would add the following code in the MainWindow

<pre lang="cs">public static readonly RoutedEvent FilterLoadedEvent = EventManager.RegisterRoutedEvent(
         "FilterLoaded", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MainWindow));

       public event RoutedEventHandler FilterLoaded
       {
           add { AddHandler(FilterLoadedEvent, value); }
           remove { RemoveHandler(FilterLoadedEvent, value); }
       }




并从MyButton触发事件为:
RaiseEvent(new RoutedEventArgs(MainWindow.FilterLoadedEvent));

一切都很好.

知道如何解决吗?

谢谢




And fire the event from the MyButton as:
RaiseEvent(new RoutedEventArgs(MainWindow.FilterLoadedEvent));

it would all work fine.

Any idea how to fix it?

Thank you


这篇关于混合EventTrigger“点击"使用常规命令时不会触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆