WPF 母控件如何将事件推送给自定义UserControl

观铃 2018-04-20 09:12:38
情形:
自定义了一个UserControl,内部有一个Button,Button实现了键盘快捷键Ctrl+S。
然后外部的Window窗口调用这个UserControl。

结果:
只有焦点在UserControl上时,才会响应快捷操作。
当焦点在其他外部控件时,不响应快捷操作。

为了保证高内聚低耦合的特性,希望外部控件也就是Window收到快捷操作事件的时候,能够将快捷操作的事件推送给UserControl,让它来响应这个事件。
请各位大神指教。
...全文
713 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
比如说 TextBox 控件具有 TextChanged 事件,它是用来通知宿主(将来组合到各种各样的控件宿主里边)这个事件的。那么假设宿主要设置文本就直接写 textbox1.Text=".....",如果要调用其 Select(start, length) 就直接调用这个方法,你还来说这个要调用TextBox 控件的什么事件?
  • 打赏
  • 举报
回复
这个不叫做“推送”,这是把模式搞过头了。你的父控件在逻辑上拥有子控件,子控件就是它动态创建的,自然是直接调用子控件的属性、方法、字段来传送数据就行了。什么“外部事件、内部事件”,这是你想多了。 依赖倒置是指,用户控件作为一种通用服务,面向各种宿主服务控件而编程设计。搞清楚什么时候才应该倒置,不可以滥用。 现在你又把依赖倒置反过来,这比根本不知道依赖倒置、不知道事件还悲催。还不如根本不知道它。
观铃 2018-04-20
  • 打赏
  • 举报
回复
引用 2 楼 qq_33911540 的回复:
UserControl1代码:
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
            button1.Click += (s, e) => Onbtn_Click(e);
        }
        private static readonly object Event_btn_Clicked = new object();

        public event EventHandler btnt_Clicked
        {
            add { base.Events.AddHandler(Event_btn_Clicked, value); }
            remove { base.Events.RemoveHandler(Event_btn_Clicked, value); }
        }

        protected virtual void Onbtn_Click(EventArgs e)
        {
            EventHandler handler =
                base.Events[Event_btn_Clicked] as EventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }
    }
Form1代码:
userControl11.btnt_Clicked += (s, e) => MessageBox.Show("点击了userControl11按钮");
你这个是UserControl内部的事件调用外部的响应。 我想的是外部的事件调用内部的响应。(在尽量松耦合的情况下)
观铃 2018-04-20
  • 打赏
  • 举报
回复
最简单的方式,就是暴露内部的事件响应“Onbtn_Click”,然后在外部的事件响应里直接调用这个响应。就做到了在外部触发事件,然后UserControl内部去响应。 但这种方法需要去调用内部事件。 所以想问一下这里的大神,有没有办法是让UserControl去监听外部的事件。外部的事件触发时,收到信号去触发内部事件。
李敢敢 2018-04-20
  • 打赏
  • 举报
回复
UserControl1代码:
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
            button1.Click += (s, e) => Onbtn_Click(e);
        }
        private static readonly object Event_btn_Clicked = new object();

        public event EventHandler btnt_Clicked
        {
            add { base.Events.AddHandler(Event_btn_Clicked, value); }
            remove { base.Events.RemoveHandler(Event_btn_Clicked, value); }
        }

        protected virtual void Onbtn_Click(EventArgs e)
        {
            EventHandler handler =
                base.Events[Event_btn_Clicked] as EventHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }
    }
Form1代码:
userControl11.btnt_Clicked += (s, e) => MessageBox.Show("点击了userControl11按钮");
观铃 2018-04-20
  • 打赏
  • 举报
回复
自己回一个暖暖人气。
xianglanyue_net 2018-04-20
  • 打赏
  • 举报
回复
你直接在这个窗体快捷键事件触发事件里,判断一下这个控件是否获取到焦点 if(控件名.IsFocused)
xuzuning 2018-04-20
  • 打赏
  • 举报
回复
你可以去学习一下 Unity 的做法 比如接口 IPointEnterHandler ,事件到来时,所有实现了他的控件都会去响应
观铃 2018-04-20
  • 打赏
  • 举报
回复
引用 8 楼 xuzuning 的回复:
如果 Window 中防止了你的两个 UserControl 那么 Ctrl+S 来临时,您打算推送给哪个 UserControl 呢?
理论上 两个都应该响应
xuzuning 2018-04-20
  • 打赏
  • 举报
回复
如果 Window 中防止了你的两个 UserControl 那么 Ctrl+S 来临时,您打算推送给哪个 UserControl 呢?
观铃 2018-04-20
  • 打赏
  • 举报
回复
引用 6 楼 sp1234 的回复:
比如说 TextBox 控件具有 TextChanged 事件,它是用来通知宿主(将来组合到各种各样的控件宿主里边)这个事件的。那么假设宿主要设置文本就直接写 textbox1.Text=".....",如果要调用其 Select(start, length) 就直接调用这个方法,你还来说这个要调用TextBox 控件的什么事件?
在MVC或者MVVM模式下, textbox1.Text="....."这种写法本身就不算好。我都说了是为了要低耦合。 如果直接控制了控件的内部,我那还不直接写在界面上,自定义一个UserControl有什么意义。

110,535

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧