2014-02-18 25 views
1

我似乎对一个简单的问题有很大的麻烦。是的,我是新来的C#,但我试图了解我能做什么,而不用跳过来发布问题。在这种情况下,我只是觉得我没有问正确的问题。使用c通信或访问另一个父母使用c#

无代码样本将帮助这里,因为我说的是基本(实现)。我还没有真正编码任何东西,只需使用视觉生成器来创建我的窗体和菜单。

我遇到的问题是,当我选择一个菜单项(称之为:集路径)我想我的主要形式,对列表视图,从选择时,我打Form2上确定的路径加载。所以我做了一个简单的查找文件夹对话框,并将我的新路径存储在form2文本框中。当我在该form2上点击确定时,我想要我的listview form1填充。我知道如何做到这一切,但我不能在我的生活中从form2访问form1,反之亦然。

我试图使一个回调函数,但我得到的,因为我的Form1上是静态的非静态变量不能被引用...错误,所以我不能创造任何非静态方法。我查看了EventArgs,但这看起来像是对这样一个常见请求的过度杀手。

那么,什么是做到这一点的一般方法是什么?

+0

一般来说,您将使用ShowDialog()显示Form2,然后在Form1中检查DialogResult.OK的结果(点击“OK”按钮时在Form2中将DialogResult设置为OK)。正如RobertHavey所解释的那样,您将使用Form2的引用来访问所需的值。缺少的成分是,您不能(默认情况下)访问存储在Form2上的TextBox中的值。您可以通过将TextBox的Modifiers()属性设置为Public来“解决”此问题。然而,首选的方法是在Form2上创建一个自定义属性来保存该值。 –

+0

完美! DialogResult正是我所需要的。我忘记了窗户的回报。 –

回答

1

对于访问另一个表单上的成员,Robert的回答是正确的。但是,一般来说,你应该保存你的应用程序的状态(称为“模型”),从用户界面的状态分别(称之为“视图”)。随着您的应用程序增长超过一个或两个交互,这变得非常重要。关于如何将两者结合在一起(例如Google的“模型 - 视图 - 控制器”(MVC)和“模型 - 视图 - 视图模型”(MVVM)),有几种哲学或模式,如果你真的想要正确地做到这一点,会推荐学习这些。我的首选是MVVM方法,即使它是在设计时考虑WPF应用程序,也可以使用Windows Forms轻松完成。

在.NET中,代码应该使用来实现您的视图模型和视图之间的连接基本片被称为INotifyPropertyChanged的接口。您创建一个实现了这个接口,并发送通知的类每当属性发生变化,因此,例如你的路径属性,你将创建这个类:

class ViewModel : INotifyPropertyChanged 
{ 
    private string path; 
    public string Path 
    { 
     get { return path; } 
     set { 
      if (value != path) 
      { 
       path = value; 
       NotifyPropertyChanged(); 
      } 
     } 
    } 

    // This event gets triggered whenever a property changes. 
    public event PropertyChangedEventHandler PropertyChanged; 

    // This will cause the event to actually be triggered. It automatically determines the name of the property that triggered it using the [CallerMemberName] attribute - just a bit of .NET 4.5 sweetness. :) 
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

它可能看起来像很多工作,但现在在你的Form1中您可以创建一个新的“ViewModel”实例,订阅该事件,然后将该实例传递给form2。然后,只要用户选择不同的路径,form2就更新视图模型实例上的Path属性。

所以,Form1中需要靠近顶部验证码:

private ViewModel viewmodel = new ViewModel(); 

而这正好在Form1构造函数:

viewmodel.PropertyChanged += new EventHandler(OnPathChanged); 

而且当你创建/显示窗口2:

var form2 = new Form2(viewmodel); // Note, the viewmodel instance is being passed to the form2 constructor 
form2.Show(); 

然后,form2构造函数将自己的引用存储到“viewmodel”实例中,并且每当th e路径被用户改变。

private ViewModel viewmodel; 

public Form2(ViewModel viewmodel) 
{ 
    this.viewmodel = viewmodel; 
    ... // Other stuff to set up your controls etc. goes here 
} 

private void PathChanged(object sender, EventArgs e) // This may be named differently in your code; it's the event handler that gets called when the path changes 
{ 
    // This will automatically notify the event handler in Form1! It's super-elegant and flexible. 
    this.viewmodel.Path = txtPath.Text; // Assuming you have a textbox called txtPath 
} 

最后事件处理程序在Form1中:

private void OnPathChanged(object sender, EventArgs e) 
{ 
    var newPath = viewmodel.Path; // Get the updated path back from the viewmodel 
    //TODO: Whatever you want to do when the path changes. 
} 

下面是使用Windows窗体一个非常好的MVVM介绍的链接,它采用两种形式就像你在你的例子都有。 MVVM (Model-View-ViewModel) Pattern For Windows Form Applications, using C#

+0

我认为这回答了最好的问题,但DialogResult是我真正想要的(对于漫长的解释,我是错的)。 –

+0

没问题。你的解释很好! (尽管一些代码片段可以很好地包含在类似的问题中,例如类名和在form1中创建/显示form2的地方),我认为看到不同的方法会很有帮助 - 您现在需要的直接解决方案,以及稍后在应用程序增长时需要的更精细的一个。 –

1

如果您需要为另一种形式的访问的东西,只是从你的第一种形式持有对它的引用,就像这样:

form2 = new Form2(); 
form2.Show(); 
form2.WhateverYouWantToAccess 

这就是说,如果你只是想从用户那里得到的文件路径,你想使用OpenFileDialog类。

private void button1_Click(object sender, System.EventArgs e) 
{ 
    Stream myStream = null; 
    OpenFileDialog openFileDialog1 = new OpenFileDialog(); 

    openFileDialog1.InitialDirectory = "c:\\" ; 
    openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*" ; 
    openFileDialog1.FilterIndex = 2 ; 
    openFileDialog1.RestoreDirectory = true ; 

    if(openFileDialog1.ShowDialog() == DialogResult.OK) 
    { 
     try 
     { 
      if ((myStream = openFileDialog1.OpenFile()) != null) 
      { 
       using (myStream) 
       { 
        // Insert code to read the stream here. 
       } 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message); 
     } 
    } 
} 
+0

不,这不是肖恩所问的。一般来说,他想知道如何解决不同形式之间的沟通问题。虽然我同意这是一个快速解决方法 - 只需将OpenFileDialog调用放入Sean的“form1”中即可 - 但它并没有真正回答这个问题。 –

+0

好的,但正如我所说的那部分我知道该怎么做,其访问回到主要形式,这是我的问题。 Thx虽然现在我看到如何处理错误。 –

+0

@LarsKemmann * [叹气] *好的,我会在我的回答中加入一些内容。但是,我不会建议有人创建自定义表单来获得路径。 –