【问题标题】:Returning updates from a method从方法返回更新
【发布时间】:2011-11-25 20:15:54
【问题描述】:

我启动了一个小应用程序(C#、.Net4、控制台应用程序),这是根据规则在家里移动文件的基本想法。

这个应用程序已经发展并变得非常有用。所以我的任务是将它分解成更多可重用的类和更小的项目(类库)。

我有一个通用的“显示”函数,它接受一个字符串和一个 error_level id。基于此,我会以某种颜色将文本输出到我的控制台窗口。当它都在一个大类中时一切都很好,但我想将一个方法移动到它自己的类库中 - 但是,我希望它在处理时向我的 UI(现在是控制台窗口)报告更新。当我将它移到类时,显然,类到我的“显示”方法,中断。

有没有办法让我从我的类方法发送消息,返回我的 UI?它的消息类似于“打开的配置文件”、“正在处理 12 个新文件”、“成功”。

当它发生时,UI 获取消息并显示它们,同时方法完成它的工作。

目前,它是一个控制台应用程序项目。我的计划是删除工作代码,保留控制台应用程序进行测试,然后将“UI”更改为一个不错的 WPF 桌面应用程序。 (我正在尝试学习 WPF,并决定使用我很久以前开始的一个小项目,并“剥皮”)。

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    我建议您添加一个接口,在您的 UI 中实现该接口,并将实现该接口的类的引用传递给您的新类。

    如果您在单个线程或多个线程中执行工作,这种方法应该可以工作。

    例如界面:

    public interface INotify
    {
        void Notify(string Msg);
    }
    

    用户界面:

    public class Form1 : INotify
    {
            // This is the method where you instantiate the new worker process
            public void DoSomeWork() {
                NewClass Worker = New NewClass(this);
            }
    
            public delegate void NotifyDelegate(string Msg);
    
        public void Notify(string Msg)
        {
            txtLog.Text += Msg + Environment.NewLine;
        }
    
        void INotify.Notify(string Msg)
        {
            this.INotify_Notify(Msg);
        }
        private void INotify_Notify(string Msg)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new NotifyDelegate(Notify), Msg);
            }
            else
            {
                this.Notify(Msg);
            }
        }
       }
    

    还有新的类(只需要在这个类中调用notify来发送消息):

    public class NewClass
    {
        private INotify m_Notifier;
    
        private void Notify(string Msg)
        {
            m_Notifier.Notify(Msg);
        }
    
        public NewClass(INotify oNotifier)
        {
            m_Notifier = oNotifier;
        }
    }
    

    使用替代实现进行更新

    与静态类一起使用的替代实现是实现委托。

    例如,这里是委托:

    public delegate void NotifyDelegate(string Msg);
    

    这是控制台应用的示例静态类:

    static class Program
    {
        private static NotifyDelegate m_Notifier;
        static void Main(string[] args)
        {
            m_Notifier = new NotifyDelegate(Notify);
    
            NewClass oNewClass = new NewClass(m_Notifier);
    
            // Your work code here
        }
        static void Notify(string Msg)
        {
            Console.WriteLine(Msg);
        }
    }
    

    以及修订版的工作类:

    public class NewClass
    {
        private NotifyDelegate m_Notifier;
    
        public void Notify(string Msg)
        {
            m_Notifier.Invoke(Msg);
        }
    
        public NewClass(NotifyDelegate oNotifier)
        {
            m_Notifier = oNotifier;
        }
    }
    

    【讨论】:

    • 谢谢,我正在尝试这个 - 但是,我目前的应用程序是一个控制台应用程序,所以我的主程序类是静态的。当我声明我的 Notify 方法时,它在我的程序中必须是静态的。 public static void Notify(string message, Constants.ErrorLevel errorLevel) 。接口声明如下: void Notify(string message, Constants.ErrorLevel errorLevel);所以,因为一个是静态的,另一个不是,我在我的 UI 上收到一个错误,说 Notify 没有被实现。我怎样才能解决这个问题?
    • 我已经更新了使用委托而不是接口来处理您的情况的答案。
    • 谢谢 - 当我转向非静态类时,当我获得 WPF 时,最好使用基于接口的解决方案,或者事件处理程序是否适合静态和非静态项目?
    • 我认为任何一个都适合,但如果您在非 UI 线程中执行工作人员,您将希望在第一种方法中使用调用机制。我个人更喜欢界面方法,因为它感觉“更干净”,但我并没有具体的理由。
    【解决方案2】:

    如果我正确理解您的问题,我将实施事件处理,以便您的 UI 可以订阅某种状态 event。 另一种方法是使用某种日志框架,如 NLog,并通过methodCall target 将日志记录到 UI 中的静态方法。 由于您使用的是 WPF,因此使用 MVVM 是有意义的。这可能是创建强大且可维护的 UI 的最佳方式。

    【讨论】:

      【解决方案3】:

      这通常是通过 Binding 完成的,您将 viewModel 与视图绑定,并且对 viewModel 的任何更改都将直接显示在您的 UI 中。

      【讨论】:

        【解决方案4】:

        工作的类能否引发 UI 线程上的类正在监听的 event? 'worker' 类会引发一个带有一些参数的事件,然后侦听器类会将该信息写入 UI。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-12
          • 2015-08-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-29
          • 1970-01-01
          相关资源
          最近更新 更多