Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Caliburn Micro从DataGridComboxColumn捕获TextChanged事件_C#_Wpf_Events_Caliburn.micro - Fatal编程技术网

C# 使用Caliburn Micro从DataGridComboxColumn捕获TextChanged事件

C# 使用Caliburn Micro从DataGridComboxColumn捕获TextChanged事件,c#,wpf,events,caliburn.micro,C#,Wpf,Events,Caliburn.micro,我在将组合框的部分文本框的TextChanged事件传递到关联的视图模型时遇到问题 正如所料: 在TextChanged上,调用代码隐藏中的OnTextChanged()方法 在KeyUp上,调用视图模型中的OnKeyUp()方法 然而: 在TextChanged上,不调用视图模型中的OnTextChanged()方法 为什么不调用它?我如何修复它 <UserControl x:Class="AutoComplete.Views.ShellView" xmlns=

我在将组合框的
部分
文本框的
TextChanged
事件传递到关联的视图模型时遇到问题

正如所料:

  • TextChanged
    上,调用代码隐藏中的
    OnTextChanged()
    方法
  • KeyUp
    上,调用视图模型中的
    OnKeyUp()
    方法
  • 然而:

  • TextChanged
    上,不调用视图模型中的
    OnTextChanged()
    方法
  • 为什么不调用它?我如何修复它

    <UserControl x:Class="AutoComplete.Views.ShellView"
                 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:cal="http://www.caliburnproject.org"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300"
                 >
        <UserControl.Resources>
            <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>
        </UserControl.Resources>
        <Grid>
            <ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"/>
            <DataGrid ItemsSource="{Binding Rows}" AutoGenerateColumns="False" CanUserAddRows="True" CanUserDeleteRows="True">
                <DataGrid.Columns>
    
                    <DataGridComboBoxColumn Header="Code">
                        <DataGridComboBoxColumn.EditingElementStyle>
                            <Style TargetType="ComboBox">
                                <EventSetter Event="TextBoxBase.TextChanged" Handler="OnTextChanged"/>
                                <Setter Property="cal:Action.TargetWithoutContext" Value="{Binding DataContext, Source={StaticResource ProxyElement}}"/>
                                <Setter Property="cal:Message.Attach" Value="[Event TextBoxBase.TextChanged] = [Action OnTextChanged($source, $dataContext)]; [Event KeyUp] = [Action OnKeyUp()]"/>
                                <Setter Property="IsEditable" Value="True"/>
                                <Setter Property="ItemsSource" Value="{Binding DataContext.Suggestions, Source={StaticResource ProxyElement}}"/>
                            </Style>
                        </DataGridComboBoxColumn.EditingElementStyle>
                    </DataGridComboBoxColumn>
    
                </DataGrid.Columns>
            </DataGrid>
    
        </Grid>
    </UserControl>
    

    这不起作用,因为Caliburn Micro默认情况下对
    消息使用
    事件触发器
    类。附加
    。根据
    EventTrigger
    使用反射查找使用
    EventName
    属性的事件,该属性失败,因为
    ComboBox
    未公开名为
    TextBoxBase.TextChanged的事件。它也不会公开
    TextChanged
    事件,应该捕获的是
    ComboBox
    TextBox
    组件中冒出的
    TextChanged

    上述职位还提供了一个适应性强的解决方案。首先,创建一个新的
    RoutedEventTrigger
    类:

    public class RoutedEventTrigger : EventTriggerBase<DependencyObject>
    {
        public RoutedEvent RoutedEvent { get; set; }
    
        protected override void OnAttached()
        {
            var element = (AssociatedObject as Behavior as IAttachedObject)?.AssociatedObject as UIElement
                      ?? AssociatedObject as UIElement;
    
            element?.AddHandler(RoutedEvent, new RoutedEventHandler(OnRoutedEvent));
        }
    
        void OnRoutedEvent(object sender, RoutedEventArgs args)
        {
            OnEvent(args);
        }
    
        protected override string GetEventName()
        {
            return RoutedEvent.Name;
        }
    }
    
    完成此设置后,可以使用冒泡路由事件

    public class Bootstrapper : BootstrapperBase
    {
        public Bootstrapper()
        {
            Initialize();
        }
    
        private RoutedEventTrigger CreateRoutedEventTrigger(DependencyObject target, string routedEvent)
        {
            var routedEvents = EventManager.GetRoutedEvents().ToDictionary(r => $"{r.OwnerType.Name}.{r.Name}");
            if (routedEvents.ContainsKey(routedEvent))
            {
                var trigger = new RoutedEventTrigger
                {
                    RoutedEvent = routedEvents[routedEvent]
                };
                trigger.Attach(target);
                return trigger;
            }
            return null;
        }
    
        protected override void OnStartup(object sender, StartupEventArgs args)
        {
            var baseCreateTrigger = Parser.CreateTrigger;
            Parser.CreateTrigger = (target, triggerText) =>
            {
                var baseTrigger = baseCreateTrigger(target, triggerText);
                var baseEventTrigger = baseTrigger as EventTrigger;
                return CreateRoutedEventTrigger(target, baseEventTrigger?.EventName ?? "") ?? baseTrigger;
            };
           ...
        }
        ...
    }