从单独的类库访问 UI 控件

本文关键字:UI 控件 访问 类库 单独 | 更新日期: 2023-09-27 18:32:26

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

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

我知道我应该使用Dispatcher来做到这一点,但我无法弄清楚如何正确设置它。谁能帮忙?

这里是 MainWindow.xaml:

<Window x:Class="WPFMainPanel.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Name="btnRun" Content="Run" HorizontalAlignment="Left" Margin="157,10,0,0" VerticalAlignment="Top" Width="75" Click="btnRun_Click"/>
        <TextBox Name="tbox_Data" HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
    </Grid>
</Window>

这里是 MainWindow.xaml.cs

namespace WPFMainPanel
{
    public partial class MainWindow : Window
    {
        private ProductionManager myManager = ProductionManager.Instance;
        private void btnRun_Click(object sender, RoutedEventArgs e)
        {
            myManager.DoSomethingElse();
        }
    }
}

这是我的经理库中的生产经理类

namespace Manager
{
    public class ProductionManager
    {
        private static ProductionManager instance;
        private ProductionManager() { }
        public static ProductionManager Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new ProductionManager();
                }
                return instance;
            }
        }
        public void DoSomethingElse()
        {
            // Change the Text Box Named tbox_Data from here
        }
    }
}

谁能帮我?

从单独的类库访问 UI 控件

你可以尝试这样的事情。

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

  public void Dosomethingelse(TextBox textBox,string yourText)
    {
        var myTextbox = textbox;
        mytextbox.text = yourText;
    }

现在,当您像这样从MainWindows.xaml.cs调用中调用该方法时,

myManager.Dosomethingelse(tbox_data,stringYouWantToAdd);
好的解决了

!,我从iJays的一个答案中找到了这种方法。

首先,您必须创建主窗口的静态变量。因此,您的图书馆可以访问它。并且必须创建一个字符串属性来设置文本框的文本。然后在该属性的 set 访问器中,您可以使用调度程序更改文本

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();
    }
}