C#两个表单访问相同的类数据

时间:2011-02-06 01:23:35

标签: c# wpf

我正在使用MS Visual C#2010。

我创建了2个WPF表单,MainWindow.xaml和CreateCharacter.xaml。我做了Project-> Add Class ...来添加一个名为Hero.cs的空类。英雄级别将保留球员姓名和其他重要数据。

在MainWindow.xaml.cs中,我创建了一个Hero类的实例:Hero player = new Hero();。我单击MainWindow上的一个按钮,它将打开CreateCharacter表单。在CreateCharacter表单上,我想输入玩家名称并将此数据存储在player.name中,该名称在MainWindow中实例化。

如何使我在MainWindow类中创建的Hero对象可用于CreateCharacter类?

4 个答案:

答案 0 :(得分:3)

如果CreateCharacter表单正在创建一个字符,那么它可能应该创建Hero实例。它可以在公共属性中返回它,主表单可以在CreateCharacter表单成功返回后读取。

答案 1 :(得分:1)

这可能是互联网论坛上有史以来最常见的问题之一 我建议您在深入了解GUI编程之前熟悉面向对象的编程,以便了解基本概念。

要将对象传递给另一个窗口,您可以添加一个特殊的构造函数,将其作为参数接受,并添加一个属性或字段来保存它(取决于您是否要使其可访问):

partial class CreateCharacterWindow : Window {
    private Character character;

    public CreateCharacterWindow ()
        : this (null) { } // designer requires parameterless constructor

    public CreateCharacterWindow (Character character)
    {
        this.character = character;
        InitializeComponent ();
    }
}

var spiderman = new Character ();
var charWindow = new CreateCharacterWindow (spiderman);

我碰巧不喜欢这种做法。

您打算在即将展示的窗口中创建字符似乎是合乎逻辑的。在窗口显示之前创建对象有什么意义? 我认为实际CreateCharacterWindow Character是真实地实例化Character,因为它最了解其属性,并且无论如何在用户按下之前没有任何意义的虚拟角色如果您不打算使用数据绑定,请创建按钮或类似的东西。

如果您打算使用数据绑定,请在CreateCharacterWindow中创建一个公共只读MainWindow属性,以便DataContext可以访问它,在构造函数中实例化它,将实例分配给{{1在XAML标记中对象和连接UI控件和对象属性。

但在这种情况下我也不会使用数据绑定。

我要做的是使用CreateCharacterWindow方法以模态方式显示ShowModal。在本课程中,如果用户选择实际创建角色(而不是按下取消按钮),我会将this.DialogResult设置为true

ShowModal将返回我们分配给DialogResult的值,因此MainWindow知道用户是否真的想要创建角色。如果是这种情况,我们最终会要求CreateCharacterWindow创建Character实例:

partial class CreateCharacterWindow : Window {

    public CreateCharacterWindow ()
    {
        InitializeComponent ();
        createButton.Click += (sender, e) => {
            this.DialogResult = true;
            this.Close ();
        };
    }

    public Character CreateCharacter ()
    {
        return new Character {
            Name = nameBox.Text
        };
    }
}

var createWindow = new CreateCharacterWindow ();
var doCreate = createWindow.ShowDialog ();

if (doCreate ?? false) { // if DialogResult was not specified, assume it's false 
    var character = createWindow.CreateCharacter ();
    // do whatever you like with it
}

这个方法缺少一些WPF数据绑定功能,但我喜欢只有在业务逻辑的角度确实 一个字符时才创建Character,并且该对象不起作用一些可能使用或不使用的占位符。

答案 2 :(得分:0)

添加到Hero类的CreateCharacter参数或属性,并将其传递给构造函数或任何其他方法。

答案 3 :(得分:0)

这是一种非常常见的模式。这是我在WPF中的表现。

在主窗口的视图模型中,应该有一个名为Characters的属性ObservableCollection<CharacterViewModel>。在视图中,这绑定到某种项控件,比如ListBoxDataTemplate或[{1}}类实现CharacterViewModel,以便有效地呈现字符。 ToString()的{​​{1}}属性绑定到视图模型中的SelectedItem属性,因此每当用户单击列表框中的项目时,视图模型就会知道当前的内容 - 选择的角色是。

主窗口视图模型还实现了一个ListBox事件(它只是一个普通的事件处理程序)和一个SelectedCharacter(使用Josh Smith's RelayCommand pattern)及其附带的属性和方法,例如:

EditingCharacter

EditCharacterCommand绑定到视图中的可点击控件(例如按钮或超链接)。

主窗口视图实例化主窗口视图模型并注册public bool CanEditCharacter { get { return SelectedCharacter != null; } } public void EditCharacter() { EventHandler h = EditingCharacter; if (EditingCharacter != null) { EditingCharacter(this, EventArgs.Empty); } } 事件的处理程序:

EditCharacterCommand

(为什么要使用事件?因为使用事件会保留在视图模型对象之外创建和显示窗口的实现细节。EditingCharacter不需要知道有关如何编辑字符的任何细节。它只是引发了一个事件,说“嘿,是时候编辑当前选中的角色了。”由主窗口决定在事件发生时它会做什么。)

private void ViewModel_EditingCharacter(object sender, EventArgs e) { CharacterViewModel cvm = ((MainWindowViewModel)sender).SelectedCharacter; CharacterWindow cw = new CharacterWindow(); cw.ShowDialog(cvm); } 实际上是让用户编辑角色的。它的控件绑定到CharacterViewModel的属性。它实现了CharacterWindow的重载:

CharacterViewModel

(可以在不保存更改的情况下取消此对话框,这对读者来说是一种练习。)

最后,您在窗口视图模型中实现ShowDialog - 它会创建一个新的public bool? ShowDialog(CharacterViewModel cvm) { DataContext = cvm; return ShowDialog(); } ,将其添加到AddCharacterCommand集合,设置{ {1}},并提出CharacterViewModel。将其绑定到主窗口中的按钮或超链接或菜单项,您就完成了。