如何在WPF(C#)中创建一个带有参数的窗口?

如何在WPF(C#)中创建一个带有参数的窗口?,c#,wpf,xaml,mvvm,C#,Wpf,Xaml,Mvvm,我第一次使用WPF(C#),这是我遇到的第一个“真正”的设计选择。我有一个主窗口,当用户输入一些数据并按下“绘图”按钮时,会出现一个显示图形的新窗口 这个图形窗口是我用xaml和代码隐藏文件的组合来定义自己的。问题是此窗口有两个参数,即x轴标题和y轴标题。所以,这些应该是制作这个窗口的“参数” 我对此感到困惑,因为我使用的是MVVM,我有一个名为GraphWindowPresenter的窗口的“视图模型”,还有一个名为GraphWindowView的类的“视图” 起初,我尝试在我的GraphWi

我第一次使用WPF(C#),这是我遇到的第一个“真正”的设计选择。我有一个主窗口,当用户输入一些数据并按下“绘图”
按钮时,会出现一个显示图形的新窗口

这个图形窗口是我用xaml和代码隐藏文件的组合来定义自己的。问题是此窗口有两个参数,即x轴标题和y轴标题。所以,这些应该是制作这个窗口的“参数”

我对此感到困惑,因为我使用的是MVVM,我有一个名为
GraphWindowPresenter
的窗口的“视图模型”,还有一个名为
GraphWindowView
的类的“视图”

起初,我尝试在我的
GraphWindowPresenter
中使用
xAxis
属性和
yAxis
属性,但这不起作用,因为在构建
GraphWindowView
时,我需要“绑定”这些值。此外,这种方法需要我的
GraphWindowPresenter
采用
xAxis
参数和
yAxis
参数,这也是一个问题,因为我只是在
GraphWindowView
的xaml中创建了类的实例

我正在考虑一个可能的解决方案,我可以让我的
GraphWindowView
使用
xAxis
yAxis
参数,但这不违反MVVM吗?我宁愿不那样做

注意:这与本文类似。但在我的场景中,这很棘手,因为我有一个父窗口和一个弹出的子窗口

问题:解决此设计问题的最佳方法是什么?关于这个场景的“最佳实践”是什么

可能的答案:

这是您描述的依赖项属性的正确用法吗?这是一个“干净”的解决方案吗

private void doGraph()
{
    if (log == null) // if a log is not loaded
    {
        MessageBoxResult mbr = MessageBox.Show("A log file must be " +
                                               "loaded before plotting.",
                                               "Warning",
                                               MessageBoxButton.OK,
                                               MessageBoxImage.Exclamation);
        return;
    }

    // NOW MUST PRESENT GRAPH WINDOW
    GraphWindowView gwv = new GraphWindowView();
    gwv.xAxis = X_AXIS_VALUE:
    gwv.yAxis = Y_AXIS_VALUE;
    gwv.Show();
}
在我的
GraphWindowView
课程中,我有以下代码:

public partial class GraphWindowView : Window
{
    // Using a DependencyProperty as the backing store for yAxis.
    public static readonly DependencyProperty yAxisProperty =
        DependencyProperty.Register("yAxis", typeof(string), typeof(GraphWindowView));

    // Using a DependencyProperty as the backing store for xAxis.
    public static readonly DependencyProperty xAxisProperty =
        DependencyProperty.Register("xAxis", typeof(string), typeof(GraphWindowView));

    public string xAxis
    {
        get { return (string)GetValue(xAxisProperty); }
        set { SetValue(xAxisProperty, value); }
    }

    public string yAxis
    {
        get { return (string)GetValue(yAxisProperty); }
        set { SetValue(yAxisProperty, value); }
    }

    public GraphWindowView()
    {
        InitializeComponent();
    }
}

您可以设置用户属性

我的一个应用程序有相同的场景,我有一个接受HostAddress、Port值的主窗口,当我单击connect时它将使用另一个窗口,所以我使用的是userSetting属性。我还在使用下面的MVVM模式检查代码片段

XAML:
<TextBox Width="120" Canvas.Left="132" Canvas.Top="16" Text="{Binding Path=Server,Mode=TwoWay}"/>
<TextBox Width="120" Canvas.Left="132" Canvas.Top="42" Text="{Binding Path=DisplayPort,Mode=TwoWay}"/>
<TextBox Width="120" Canvas.Left="132" Canvas.Top="69" Text="{Binding Path=CtrlPort,Mode=TwoWay}"/>
<Button Content="Launch" Name="btnLaunch" Command="{Binding Path=appSetting}" Canvas.Left="132" Canvas.Top="100" Width="120" Height="51" Click="btnLaunch_Click" />

VIEWMODE:
public class SettingsViewModel : ViewModelBase
{
    private Settings _settings { get; set; }

    public SettingsViewModel()
    {
        appSetting = new RelayCommand(this.AppSettingsCommand);
        _settings = ApplicationTest.Properties.Settings.Default;
    }

    private string _server = Settings.Default.Server;
    public string Server
    {
        get { return this._server; }
        set
        {
            if (this._server != value)
            {
                this._server = value;
                OnPropertyChanged("Server");
            }
        }
    }

    private string _displayPort = Settings.Default.DisplayPort;
    public string DisplayPort
    {
        get { return this._displayPort; }
        set
        {
            if (this._displayPort != value)
            {
                this._displayPort = value;
                OnPropertyChanged("DisplayPort");
            }
        }
    }

    private string _ctrlPort = Settings.Default.CtrlPort;
    public string CtrlPort
    {
        get { return this._ctrlPort; }
        set
        {
            if (this._ctrlPort != value)
            {
                this._ctrlPort = value;
                OnPropertyChanged("DisplayPort");
            }
        }
    }

    public RelayCommand appSetting
    {
        get;
        set;
    }

    private void AppSettingsCommand()
    {
        this._settings.Server = this.Server;
        this._settings.DisplayPort = this.DisplayPort;
        this._settings.CtrlPort = this.CtrlPort;
        this._settings.Save();
    }
XAML:
视图模式:
公共类设置viewmodel:ViewModelBase
{
私人设置_设置{get;set;}
公共设置视图模型()
{
appSetting=新的RelayCommand(this.AppSettingsCommand);
_设置=ApplicationTest.Properties.settings.Default;
}
私有字符串_server=Settings.Default.server;
公共字符串服务器
{
获取{返回此。_server;}
设置
{
if(此._服务器!=值)
{
这个。_server=value;
OnPropertyChanged(“服务器”);
}
}
}
私有字符串_displayPort=Settings.Default.displayPort;
公共字符串显示端口
{
获取{返回此。\u displayPort;}
设置
{
如果(此._displayPort!=值)
{
这是。_displayPort=值;
OnPropertyChanged(“显示端口”);
}
}
}
私有字符串_ctrlPort=Settings.Default.ctrlPort;
公共字符串CtrlPort
{
获取{返回此。\u ctrlPort;}
设置
{
如果(此.\u ctrlPort!=值)
{
此值为.\u ctrlPort=值;
OnPropertyChanged(“显示端口”);
}
}
}
公共中继命令应用设置
{
得到;
设置
}
私有无效应用程序设置命令()
{
this.\u settings.Server=this.Server;
this.\u settings.DisplayPort=this.DisplayPort;
此._settings.CtrlPort=此.CtrlPort;
这是。_settings.Save();
}

MVVM是关于将业务逻辑与UI问题分离的。它不是关于删除代码隐藏。如果所有窗口需要的都是x轴和y轴值,则在类型扩展窗口中将它们作为依赖属性公开,然后就可以了。无需担心。感谢您的回复!我已经阅读了很多关于依赖属性的内容,但我并不完全了解它们了解它们。你能详细介绍一下在我解释的这个场景中它们将如何帮助我,也许这会让我了解它们的有用性吗?再次感谢!你会使用DP,因为它是在UI类型上定义的,可能会参与绑定(如果不是从外部,则从窗口定义本身内部,例如自定义窗口中的控件)。您也可以输入它,但DP通常是UI元素的使用方式。DependencyProperties只是使用绑定基础结构进行存储的POCO属性。DPs是WPF中可用的最快的绑定,并具有许多其他好处。是的,一开始有点奇怪,但我一直使用em。哦,好的。那么我只是使用这些b吗作为类的常规静态属性,我在上面添加了生成的代码片段(根据您的建议)。这是处理此问题的正确方法吗?只需将它们用作静态字段…?顺便说一句,此代码位于我的主父窗口的ViewModel中,名为
MainWindowPresenter
。在xaml中是否也能做到/更好?DP模式比“静态字段”复杂得多。你可以在MSDN上阅读所有关于它的内容;有一篇关于它们的非常好的文章,你可以很容易地找到。而且,是的,严格来说,UI问题不应该在你的VM中处理。感谢你的回复!我明白你的意思,但这些属性并不是真正的“用户设置”。它们实际上不是用户专门设置的。我知道此解决方案的工作原理,但我不知道这是最佳解决方案。您是否同意,或者我是否误解了这一点?您可以在viewmodel中设置值。您可以找到所有属性将设置用户在主连接窗口中提供的内容。您能告诉我xAxis和yAxis v的位置吗价值出现在你的场景中?我的xAxis和yAxis