2011-02-06 3 views
0

Я использую MS Visual C# 2010.C# Две формы, обращающаяся одни и те же данные класса

я создал 2 WPF форму, MainWindow.xaml и CreateCharacter.xaml. Я сделал Project-> Add Class ..., чтобы добавить пустой класс под названием Hero.cs. Класс Hero будет содержать имя игрока и другие важные данные.

В MainWindow.xaml.cs я сделал экземпляр класса Hero: Hero player = new Hero();. Я нажимаю кнопку на MainWindow и открывает форму CreateCharacter. В форме CreateCharacter я хочу ввести имя игрока и сохранить эти данные в файле player.name, который был создан в MainWindow.

Как создать объект Hero, который я создал в классе MainWindow, доступном для класса CreateCharacter?

ответ

3

Если форма CreateCharacter создает символ, возможно, он должен создать экземпляр Hero. Он может вернуть его в публичном свойстве, которое основная форма могла бы прочитать после успешного возврата формы CreateCharacter.

0

Добавьте к своему аргументу CreateCharacter или свойству класса Hero и передайте его его конструктору или любому другому методу.

+0

переход к конструктору - неправильный – Snowbear

+1

@Snowbear - Почему это неправильно? –

+0

@ Кирк, мы говорим о создании нескольких конструкторов? – Snowbear

1

Это, вероятно, один из самых распространенных вопросов, когда-либо задаваемых на интернет-форумах.
Я предлагаю вам ознакомиться с объектно-ориентированным программированием перед погружением в программирование графического интерфейса, чтобы вы поняли основные понятия.

Чтобы передать объект в другое окно, вы можете добавить специальный конструктор, который принимает его в качестве параметра, а свойство или поле, чтобы держать его (в зависимости от того, хотите ли вы, чтобы сделать его доступным или нет):

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 «s страх и риск на самом деле экземпляр Character, потому что он знает больше всего о его свойствах, и в любом случае нет никакого смысла в том, фиктивный характер, прежде чем пользователь нажмет Создать кнопку или что-то подобное, если вы не планируете использовать привязку данных ,

Если вы собираетесь использовать привязку данных, создать общедоступную для чтения Character собственности в CreateCharacterWindow так MainWindow может получить доступ к его, создать его экземпляр в конструкторе, назначить экземпляр DataContext объекта и проволочные элементы управления пользовательского интерфейса и свойств объекта в XAML разметке.

Но я бы не использовал привязку данных в этом случае.

Что бы я хотел сделать, это показать CreateCharacterWindow modally с помощью метода 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 только будет создаваться, когда на самом деле является персонаж из бизнес-логики точки и объект не действует как какой-либо заполнитель, который может использоваться или не использоваться.

0

Это довольно распространенный шаблон. Вот как я это сделаю в WPF.

В модели модели для главного окна должно быть свойство, называемое Characters, это ObservableCollection<CharacterViewModel>. По мнению, это связано с контролем какого-либо элемента, скажем ListBox. Существует либо для CharacterViewModel, либо класс реализует ToString(), так что символы представлены с пользой. Свойство SelectedItem объекта ListBox привязано к объекту 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. Привяжите это к кнопке или гиперссылке или пункту меню в главном окне, и все готово.