简体   繁体   English

在Visual Studio 2015中引用另一个项目

[英]Referencing another project in Visual Studio 2015

Here is the scenario I have 2 C# windows form projects, Project A and Project B. Project A has a textbox and a button. 这是我有2个C#Windows窗体项目项目A和B的情况。项目A有一个文本框和一个按钮。 When the button is pressed, whatever value is in the textbox is saved in another class. 当按下按钮时,文本框中的任何值都会保存在另一个类中。 We will call this ClassA and it is saved through ClassA.myString = textbox.Text; 我们将其称为ClassA ,它将通过ClassA.myString = textbox.Text;保存ClassA.myString = textbox.Text; .

public class ClassA
{
   public String myString
   {
      get;
      set;
   }
}

Now project B has a button and a label. 现在,项目B具有一个按钮和一个标签。 When the button is pressed, it should set the label to whatever the value that was saved into ClassA in project A. I have already established a reference through right click the project, click Add, Reference, and point to Project A from Project B. I have using ProjectA; 当按下按钮时,它应该将标签设置为项目A中保存到ClassA中的任何值。我已经通过右键单击项目,单击添加,引用,并从项目B指向项目A来建立引用。我正在使用ProjectA; inside my project B form, but I am unable to get the value to pull over. 在我的项目B表单中,但是我无法获取价值。 Below is one method I have tried that failed. 以下是我尝试失败的一种方法。

using ProjectA;

namespace projectBSolution
{
   public class ProjectB
   {
      ClassA myClass;
      public ProjectB()
      {
          InitializeComponent();
          myClass = new ClassA();
      }
      private void btn_click(object sender, EventArgs e)
      {
         label1.Text = myClass.myString;
      }
   }
}

The problem with this is it does not return my value because I am initializing a new version of the class. 问题是它不会返回我的值,因为我正在初始化该类的新版本。 If I do not initialize a new version though, it returns null every time. 但是,如果我不初始化新版本,则每次都会返回null。 Any help is appreciated. 任何帮助表示赞赏。 Thank you. 谢谢。

如果这些项目在不同的进程中运行,则必须使用一种机制进行进程间通信,请查看此链接http://weblogs.asp.net/ricardoperes/local-machine-interprocess-communication-网

If you're okay with using components of one project inside the other, but not run them as two separate executables, then it's a very simple matter. 如果您可以在另一个项目中使用一个项目的组件,但又不能将它们作为两个单独的可执行文件运行,那么这很简单。 Here I'm assuming that you're using WPF, but you can apply similar technique to WinForms or any other framework you're using: 在这里,我假设您正在使用WPF,但是您可以将类似技术应用于WinForms或您使用的任何其他框架:

App A: 应用程式A:

<Window x:Class="SampleApp.A.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SampleApp.A"
        mc:Ignorable="d"
        Title="A" 
        SizeToContent="WidthAndHeight">
    <StackPanel>
        <TextBox x:Name="textBox" VerticalAlignment="Center"
                 Width="250" Margin="10" Height="30"/>
        <Button Content="Save" Width="80" Margin="10" Click="Button_Click"/>
    </StackPanel>
</Window>

using System.Windows;

namespace SampleApp.A
{
    public partial class MainWindow : Window
    {
        public string Text { get; set; }

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Text = textBox.Text;
        }
    }
}

App B: 应用B:

<Window x:Class="SampleApp.B.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SampleApp.B"
        mc:Ignorable="d"
        Title="B" 
        SizeToContent="WidthAndHeight">
    <StackPanel>
        <Label x:Name="label" VerticalAlignment="Center" 
               Width="250" Margin="10" Height="30"/>
        <Button Content="Load" Width="80" Margin="10" Click="Button_Click"/>
    </StackPanel>
</Window>
using System.Windows;

namespace SampleApp.B
{
    public partial class MainWindow : Window
    {
        private A.MainWindow A;

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            A = new A.MainWindow();
            A.Show();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            label.Content = A.Text;
        }
    }
}

Note that I'm making this as plain as possible. 请注意,我正在尽可能使它简单。 Ideally, you would make use of INotifyPropertyChanged , MVVM and a whole bunch of other design techniques and patterns, which are clearly missing from this example. 理想情况下,您将使用INotifyPropertyChanged ,MVVM和其他许多设计技术和模式,这些示例显然不存在。

What that example does show is that you can have one project start a window from another project and access its public properties. 该示例确实表明,您可以让一个项目从另一个项目开始一个窗口并访问其公共属性。 Of course, it's not two executables interacting. 当然,不是两个可执行文件交互。 If separate executables is what you're aiming at, then the options get a bit tricky and they vary from Interop window handles to messaging and lots of things in between. 如果您要针对的是单独的可执行文件,那么这些选项会有些棘手,并且从Interop窗口句柄到消息传递以及介于两者之间的许多内容,都可能有所不同。

You could, for example, use IO.Pipes to handle your messaging routine. 例如,您可以使用IO.Pipes处理您的消息传递例程。 Below is an example of that, but it's incredibly crude, lacks lots of safety checks and will probably crash after a few minutes of use (I don't have time to test, as I'm heading out). 下面是一个例子,但它简直令人难以置信,缺乏大量的安全检查,使用几分钟后可能会崩溃(我没有时间去测试,因为我正准备前往)。 It works similarly to the above example -- you type in text in App A, click on Save and then click on Load in App B. You'll notice that App A will be frozen until you read in text in App B. Like I said, this is not meant as a production app and is simply a proof of concept. 它的工作原理与上述示例类似-您在App A中输入文本,单击“保存”,然后在App B中单击“加载”。您会注意到App A将被冻结,直到您在App B中阅读文本为止。说,这并不意味着作为生产应用程序,而仅仅是概念的证明。 I guarantee it'll do something wrong -- it's meant purely as an example to build on. 我保证它会做错事情-纯粹是作为示例继续进行。

App A: 应用程式A:

using System.IO;
using System.IO.Pipes;
using System.Windows;

namespace SampleApp.A
{
    public partial class MainWindow : Window
    {
        private NamedPipeClientStream pipeClient;
        public string Text { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
            this.Closing += MainWindow_Closing;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            pipeClient = new NamedPipeClientStream(".", "1234", PipeDirection.Out);
            pipeClient.Connect();
        }

        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            pipeClient?.Close();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Text = textBox.Text;

            using (var sw = new StreamWriter(pipeClient))
            {
                sw.WriteLine(Text);
                sw.Flush();
            }
        }
    }
}

App B : 应用B

using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Threading.Tasks;
using System.Windows;

namespace SampleApp.B
{
    public partial class MainWindow : Window
    {
        private NamedPipeServerStream pipeServer;
        public string Text { get; set; }

        public MainWindow()
        {
            InitializeComponent();
            this.Loaded += MainWindow_Loaded;
            this.Closing += MainWindow_Closing;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            Process.Start(@"C:\Users\bk\Desktop\SampleApp V2\SampleApp.A\bin\Debug\SampleApp.A.exe");
            pipeServer = new NamedPipeServerStream("1234", PipeDirection.In);
            pipeServer.WaitForConnection();
        }

        private void MainWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (pipeServer.IsConnected)
            {
                pipeServer.Disconnect();
            }
            pipeServer.Close();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (pipeServer.IsConnected)
            {
                using (var sr = new StreamReader(pipeServer))
                {
                    Text = sr.ReadLine();
                }
            }

            label.Content = Text;
        }
    }
}

Ideally, you would have a loop or an event that keeps track of incoming stream content, rather than having to press the button to get it. 理想情况下,您将有一个循环或事件来跟踪传入的流内容,而不必按下按钮来获取它。

On top of this option, you have lots of other great options such as WCF and MSMQ . 在此选项之上,您还有许多其他不错的选择,例如WCFMSMQ They're a lot more robust and worth learning. 它们更加强大,值得学习。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM