在 C#/WPF 中打开新窗口并向其传递参数的语法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25164079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:17:49  来源:igfitidea点击:

Syntax for opening a new window and passing a parameter to it in C#/WPF

c#wpf

提问by user316117

In my C#/WPF app the user can click a button to create a new window to display some graphics. Currently the code in the button handler looks like this . . .

在我的 C#/WPF 应用程序中,用户可以单击一个按钮来创建一个新窗口来显示一些图形。目前按钮处理程序中的代码如下所示。. .

var window = (Window)System.Windows.Application.LoadComponent(new Uri("ShowGraphics.xaml", UriKind.Relative));
window.Owner = this;  // keeps the Window on top of the parent window
window.Title = "Show Graphics";
window.Left = 700;
window.Top = 500;
window.Show();

Now I want to pass a parameter to the constructor of my new window using constructor syntax, something like this (pseudocode . . . )

现在我想使用构造函数语法将一个参数传递给我的新窗口的构造函数,就像这样(伪代码......)

  Window myWindow = new Window("ParameterValue");
  myWindow.Show();

... but I don't know what the right syntax is for declaring the window with its associated XAML file and other properties and passing a parameter to be read in the constructor of the new window.

...但我不知道使用关联的 XAML 文件和其他属性声明窗口并传递要在新窗口的构造函数中读取的参数的正确语法是什么。

PS - and while we're on the subject, how do I return a value back to the main window where the button was?

PS - 当我们讨论这个主题时,我如何将一个值返回到按钮所在的主窗口?

An Answer to the first partI think this is what Roman Ko was trying to get at when he wrote

对第一部分的回答我认为这就是 Roman Ko 在写作时想要达到的

"public partial class TestDialog : Window"

but instead of deriving it from the .Net Window class what I needed to do was derive it from my specific wizard-created class (Add > New Item... in VS2010). Because Visual Studio creates both the .cs file, and the .xaml file at that time, the window is associated with its XAML layout through that means. Then to pass the parameter, just do it via the constructor. Thus invoking it . . .

但我需要做的不是从 .Net Window 类派生它,而是从我特定的向导创建的类(在 VS2010 中添加 > 新项目...)派生它。由于 Visual Studio 会同时创建 .cs 文件和 .xaml 文件,因此窗口通过这种方式与其 XAML 布局相关联。然后传递参数,只需通过构造函数即可。从而调用它。. .

    var window = new TheNameSpace.ShowGraphics("parameter"); 
    window.Owner = this;  // keeps the Window on top of the parent window
    window.Title = "Show Graphics";
    window.Left = 700;
    window.Top = 500;
    window.Show();

... and consuming it in the constructor . . .

...并在构造函数中使用它。. .

public ShowGraphics(String sParam)
{
    InitializeComponent();
    // do stuff
}

An Answer to the PSOne way is to override a method of the child window, e.g., show()

对 PS 的回答一种方法是覆盖子窗口的方法,例如show()

// Override Show()
public void Show (out string sResult)
{
    Show();  // call the base class method
    sResult = "foo";
    return;
}

... then, in the caller ...

......然后,在调用者......

string sReturnVal;
window.Show(out sReturnVal); 

回答by rtlayzell

Sorry, I should have been clearer, you cannot create an instance via Application.LoadComponent, StartupUri, or any other XAML based instantiation method available without a parameter-less constructor (it relies on there being one). If you would like to provide a constructor with parameters you can create your window as you did in your second snippet:

抱歉,我应该更清楚,如果没有无参数构造函数(它依赖于构造函数),则无法通过Application.LoadComponentStartupUri或任何其他基于 XAML 的实例化方法创建实例。如果您想为构造函数提供参数,您可以像在第二个代码段中一样创建窗口:

var window = new ShowGraphics("parameter-value");
window.Show( );

回答by romanoza

Try something like this (if you don't want to follow the MVVM pattern):

尝试这样的事情(如果你不想遵循 MVVM 模式):

public partial class MainWindow : Window
{
    public MainWindow() {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e) {
        string inputParam = "some value";
        string outputValue;
        TestDialog dlg = new TestDialog(inputParam);
        if (dlg.ShowDialog() == true)
            outputValue = dlg.OutputParam;
    }
}

public partial class TestDialog : Window
{
    public TestDialog() {
        InitializeComponent();
    }

    public TestDialog(string inputParam) {
        InitializeComponent();
        OutputParam = inputParam.ToUpper(); // for example
    }

    public string OutputParam { get; private set; }

    private void btnOK_Click(object sender, RoutedEventArgs e) {
        DialogResult = true;
    }

}

回答by rtlayzell

In 99% of cases, you do not need to explicitly tell WPF where or what the XAML is for a Windowcontrol you create. The code to do this is generated for you and executed by the InitializeComponentmethod defined in the generated code

在 99% 的情况下,您不需要明确告诉 WPFWindow您创建的控件的 XAML 在哪里或它是什么。为您生成执行此操作的代码,并由InitializeComponent生成的代码中定义的方法执行

Here is a cut and paste of the generated code created for the MainWindowin a WPF application.

这是为MainWindowWPF 应用程序中创建的生成代码的剪切和粘贴。

MainWindow.g.i.cs

主窗口.gics

/// <summary>
/// MainWindow
/// </summary>
public partial class MainWindow : System.Windows.Window, System.Windows.Markup.IComponentConnector {

    private bool _contentLoaded;

    /// <summary>
    /// InitializeComponent
    /// </summary>
    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
    public void InitializeComponent() {
        if (_contentLoaded) {
            return;
        }
        _contentLoaded = true;
        System.Uri resourceLocater = new System.Uri("/WpfApplication1;component/mainwindow.xaml", System.UriKind.Relative);

        #line 1 "..\..\MainWindow.xaml"
        System.Windows.Application.LoadComponent(this, resourceLocater);

        #line default
        #line hidden
    }

    [System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
    [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
    void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
        this._contentLoaded = true;
    }
}

I repeat, you do not write/edit this code, it is generated for you automatically.All you need to do is call the constructor for your custom Window- ShowGraphics- and be sure the constructor you do call invokes the InitializeComponentmethod.

我再说一遍,您无需编写/编辑此代码,它会自动为您生成。所有你需要做的是调用构造函数的自定义Window- ShowGraphics-并确保你做调用构造函数调用的InitializeComponent方法。

If you want to take a look at your own generated code, you can find it in the $(ProjectDirectory)/obj/$(Configuration)/ folder.

如果您想查看自己生成的代码,可以在 $(ProjectDirectory)/obj/$(Configuration)/ 文件夹中找到它。