Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.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# 从单独的类库访问UI控件_C#_Wpf_Xaml_Dispatcher - Fatal编程技术网

C# 从单独的类库访问UI控件

C# 从单独的类库访问UI控件,c#,wpf,xaml,dispatcher,C#,Wpf,Xaml,Dispatcher,我的解决方案包含一个名为Manager的库(其中一个类名为ProductionManager)以及一个WPF项目。 我想要ProductionManager类的一种方法来访问WPF的UIcontrol,我该怎么做 更具体地说,我的UI有一个按钮和一个文本框。按下按钮,我从我的库中调用一个方法,我想从中更新UI窗口中的TextBox 我知道我应该使用调度程序来执行此操作,但我不知道如何正确设置它。有人能帮忙吗 此处显示MainWindow.xaml: 这里是我的经理库中的ProductionMan

我的解决方案包含一个名为Manager的库(其中一个类名为ProductionManager)以及一个WPF项目。 我想要ProductionManager类的一种方法来访问WPF的
UIcontrol
,我该怎么做

更具体地说,我的
UI
有一个按钮和一个
文本框
。按下按钮,我从我的库中调用一个方法,我想从中更新
UI
窗口中的
TextBox

我知道我应该使用
调度程序
来执行此操作,但我不知道如何正确设置它。有人能帮忙吗

此处显示MainWindow.xaml:

这里是我的经理库中的ProductionManager类


有人能帮我吗?

你可以试试这样的东西

Dosomethingelse()方法中,获取对文本框的引用

  public void Dosomethingelse(TextBox textBox,string yourText)
    {
        var myTextbox = textbox;
        mytextbox.text = yourText;
    }
现在,当您从
MainWindows.xaml.cs
调用此方法时

myManager.Dosomethingelse(tbox_data,stringYouWantToAdd);

好的,解决了!,我从s的一个答案中找到了这个方法

首先,必须为主窗口创建一个静态变量。所以你的图书馆可以访问它。您必须创建一个字符串属性来设置文本框的文本。然后在该属性的设置访问器中,您可以使用dispatcher更改文本

MainWindow.xaml.cs

 public partial class MainWindow : Window
{
    public ProductionManager myManager;
    public MainWindow()
    {
        InitializeComponent();
        myManager = new ProductionManager();
        window = this;
    }

    internal static MainWindow window;

    public string myString
    {
        get { return myTextBox.Text; }
          //this is where you change the text of your text box
        set { Dispatcher.Invoke(new Action(() => { myTextBox.Text = value; })); }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        myManager.DoSomething("Hello world");
    }
}
现在编辑“DoSomething()”方法,如下所示:

 public void Dosomethingelse(string text)
{
    MainWindows.window.myString = text;
}

可以使用事件系统和SynchronizationContext类,这样就不需要额外的库

namespace Manager
{
    public class ProductionManager
    {
        private static ProductionManager instance;
        
        // Store the UI context
        private readonly SynchronizationContext _UIContext;
        
        // Define event handler signature
        public delegate void TextChangedHandler(object sender, TextEventArgs e);

        // Define the event to listen for in your MainWindow
        public event TextChangedHandler TextChangeEvent;

        private ProductionManager() 
        { 
            // Set the SynchronizationContext, make sure to call your Instance from the MainWindow
            _UIContext = SynchronizationContext.Current;
        }

        public static ProductionManager Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ProductionManager();
                }
                return instance;
            }
        }

        public void DoSomethingElse()
        {
            // Don't change the TextBox here send the event to the MainWindow instead
            // Use the SynchronizationContext to invoke the event
            _UIContext.Send(o => TextChangeEvent?.Invoke(this, new TextEventArgs("Hello World!"), null);
        }
    }
    // The TextEventArgs, change for your needs.
    public class TextEventArgs : EventArgs
    {
        public TextEventArgs(string text) : base()
        {
            Text = text;
        }

        public string Text { get; }
    }
}
更改主窗口

public partial class MainWindow : Window
{
    private ProductionManager myManager = ProductionManager.Instance;

    public MainWindow()
    {
        InitializeComponent();

        // Hookup the event listener
        myManager.TextChangeEvent += UpdateTextBox;
    }

    private void UpdateTextBox(object sender, TextEventArgs e)
    {
        // Finally handle your text change here
        tbox_Data.Text = e.Text;
    }

    private void btnRun_Click(object sender, RoutedEventArgs e)
    {
        myManager.DoSomethingElse();
    }
}

您希望在
Dosomethingelse
方法中处理的逻辑,在其他库中放置与UI控件相关的逻辑不是一个好的做法。在Dosomethingelse中,我希望将textbox.Text属性更改为“Hello World”。总之,我正试图通过这个简单的应用程序了解更多关于dispatcher的信息。TanksYou可以这样做,
public void Dosomethingelse(Button dobject){Dispatcher.Invoke((Action)(()=>dobject.Content=“Hello World”);}
我想这样做,但如果我这样做,我将不得不将我的库与WPF应用程序紧密结合。如果我可以从库中调用UI的调度程序,我就可以访问任何UI控件,而无需对单个方法进行任何引用。我甚至想在ProductionManager.cs中添加一个公共窗口myWin。我可以在initialize()之后立即在MainWindow.xaml.cs中初始化myWin;呼叫你觉得呢?我觉得你应该多了解一下调度员。我们使用dispatcher来确定任务的优先级。本文将对您有所帮助,谢谢您,但是虽然解决方案中的WPF项目引用了库,但我的库没有引用WPF以避免循环引用。这意味着库无法识别MainWindows类。你能解决这个问题吗?你可以通过使用Action来解决这个问题,但我不知道如何使用dispatcher来解决这个问题。因为您无法通过UIs的dispatcher从库类访问ui线程。因为该调度程序属于UI线程。
 public void Dosomethingelse(string text)
{
    MainWindows.window.myString = text;
}
namespace Manager
{
    public class ProductionManager
    {
        private static ProductionManager instance;
        
        // Store the UI context
        private readonly SynchronizationContext _UIContext;
        
        // Define event handler signature
        public delegate void TextChangedHandler(object sender, TextEventArgs e);

        // Define the event to listen for in your MainWindow
        public event TextChangedHandler TextChangeEvent;

        private ProductionManager() 
        { 
            // Set the SynchronizationContext, make sure to call your Instance from the MainWindow
            _UIContext = SynchronizationContext.Current;
        }

        public static ProductionManager Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ProductionManager();
                }
                return instance;
            }
        }

        public void DoSomethingElse()
        {
            // Don't change the TextBox here send the event to the MainWindow instead
            // Use the SynchronizationContext to invoke the event
            _UIContext.Send(o => TextChangeEvent?.Invoke(this, new TextEventArgs("Hello World!"), null);
        }
    }
    // The TextEventArgs, change for your needs.
    public class TextEventArgs : EventArgs
    {
        public TextEventArgs(string text) : base()
        {
            Text = text;
        }

        public string Text { get; }
    }
}
public partial class MainWindow : Window
{
    private ProductionManager myManager = ProductionManager.Instance;

    public MainWindow()
    {
        InitializeComponent();

        // Hookup the event listener
        myManager.TextChangeEvent += UpdateTextBox;
    }

    private void UpdateTextBox(object sender, TextEventArgs e)
    {
        // Finally handle your text change here
        tbox_Data.Text = e.Text;
    }

    private void btnRun_Click(object sender, RoutedEventArgs e)
    {
        myManager.DoSomethingElse();
    }
}