2011-02-06 86 views
0

我正在使用MS Visual C#2010。C#兩種形式訪問相同的類數據

我創建了2個WPF窗體,MainWindow.xaml和CreateCharacter.xaml。我做了Project-> Add Class ...來添加一個名爲Hero.cs的空類。英雄級將保存球員姓名和其他重要數據。

在MainWindow.xaml.cs我做了英雄類的一個實例:Hero player = new Hero();。我單擊MainWindow上的一個按鈕,它將打開CreateCharacter表單。在CreateCharacter表單上,我想輸入玩家姓名並將這些數據存儲在在MainWindow中實例化的player.name中。

怎樣使我在主窗口類創建的英雄對象提供給CreateCharacter類?

回答

3

如果CreateCharacter形式是創建一個角色,那麼或許應該創建英雄實例。它可以在CreateCharacter表單成功返回後主表單可以讀取的公共屬性中返回。

0

添加到英雄職業的你CreateCharacter參數或屬性,並把它傳遞給它的構造或任何其他方法。

+0

傳遞給構造函數 - 錯誤 – Snowbear 2011-02-06 01:29:53

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的reponsibility實際實例Character,因爲它知道大多數關於它的性能,反正有在用戶按下創建按鈕或類似的東西,如果你不打算使用數據綁定之前有無效字符沒有意義。

如果你打算使用數據綁定,創建CreateCharacterWindow所以MainWindow可以訪問它,在構造函數實例化,實例分配給XAML標記DataContext對象來包裝UI控件和對象屬性的公共只讀Character財產。

但我不會在這種情況下使用數據綁定兩種。

我會做的是用ShowModal模式顯示CreateCharacterWindow模式。如果用戶選擇實際創建角色(例如,相對於按下「取消」按鈕),在此課程中,我會將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只被創建視圖,並且該對象不像某個可能使用或不可使用的佔位符。

0

這是一個很常見的模式。這是我如何在WPF中完成的。

在主窗口的視圖模型中,應該有一個名爲Characters的屬性,即ObservableCollection<CharacterViewModel>。在視圖中,這是必然的某種物品控制,說一個ListBox。對於CharacterViewModel,有一個DataTemplate,或者類實現ToString(),這樣字符就可以有效地顯示。 ListBoxSelectedItem屬性綁定到視圖模型中的SelectedCharacter屬性,以便每當用戶單擊列表框中的項目時,視圖模型就知道當前選定的字符是什麼。

主窗口視圖模型還實現了一個EditingCharacter事件(它只是一個普通的事件處理程序)和EditCharacterCommand(使用Josh Smith's RelayCommand pattern),和它的伴隨的屬性和方法,例如:

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模型 - 它創建一個新的CharacterViewModel,將其添加到Characters集合中,設置SelectedCharacter,並提升EditingCharacter。將其綁定到主窗口中的按鈕或超鏈接或菜單項,即可完成。

相關問題