从单独的类库中访问UI控件

时间:2016-01-29 02:48:25

标签: c# wpf xaml dispatcher

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

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

我知道我应该使用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();
        }
    }
}

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

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
        }
    }
}

有人可以帮我吗?

3 个答案:

答案 0 :(得分:0)

你可以尝试这样的事情。

xrealloc_dp方法中获取对文本框的引用。

Dosomethingelse()

现在,当你从 public void Dosomethingelse(TextBox textBox,string yourText) { var myTextbox = textbox; mytextbox.text = yourText; } 这样调用方法调用方法时,

MainWindows.xaml.cs

答案 1 :(得分:0)

好的解决了!我从iJay s&#39;之一找到了这个方法。答案。

首先,您必须创建MainWindow的静态变量。所以你的图书馆可以访问它。并且您必须创建一个字符串属性来设置文本框的文本。然后在该属性的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()&#39;方法如下,

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

答案 2 :(得分:0)

您可以使用事件系统和 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();
    }
}