2016-05-18 6 views
3

Я изучаю WPF MVVM и хочу открыть новое окно при нажатии кнопки в главном окне.Открытие нового окна при нажатии кнопки WPF MVVM

Я знаю, что каждый вид должен иметь эквивалентную ViewModel, и одним из основных принципов MVVM является то, что ViewModel не должен ничего знать о представлении.

Так, пожалуйста, кто-нибудь может предоставить мне простой чистый пример, который не нарушает каких-либо принципов MVVM о том, как создать два Вида и два ViewModels, которые имеют следующие функциональные возможности:

Показать новый вид, нажав кнопку с основной вид.

+0

Когда дело доходит до открытия нового окна для MVVM, становится сложнее. Одна из основных причин заключается в том, что 'DataTemplate' не позволяет вам определять внутри класса' Window'. В сети много статей, дающих много разных методов. Я бы предложил сначала попробовать их прочитать. У каждого метода есть свои плюсы и минусы, и, как правило, они не следуют 100% принципам MVVM. – Jai

ответ

0

В зависимости от вашего использования, нет ничего плохого в открытии вида из кода кода. Он по-прежнему посмотреть код в конце концов.

MyView view = new MyView(); 
view.Show(); 

В противном случае, если вам нужно, чтобы открыть окно с ViewModel или с помощью ICommand, то вы можете посмотреть на «Открыть окна и диалоги в MVVM» библиотеки, которую я написал на GitHub. Это покажет, как открыть Window, щелкнув по кнопке с использованием шаблона проектирования MVVM.

+0

Я также новичок в WPF и MVVM. Но, насколько я понимаю, это очень плохой подход. Причина в том, что ваша ViewModel становится неинтегрируемой, когда вы это делаете. Если вы вытащите всю папку ViewModel и выбросите ее в новый проект без существования View, то ваш код не собирается компилироваться и запускаться. – Jai

+0

Я не уверен, что вы полностью поняли мой ответ здесь. Позади кода я имею в виду код ** view **, а не код модели представления. –

+0

Извините, мой плохой, я думал, что код из ViewModel. – Jai

0

То, что я делал с некоторым успехом в прошлом, - это создать то, что является в основном View Factory, которое создает представление и назначает ему viewmodel. Это дает мне единый магазин, чтобы делать стихи для просмотров, как и вы, используя IoC.

Для этого могут быть преимущества и недостатки, поэтому мне было бы интересно узнать, есть ли другие/лучшие способы, но до сих пор это практика, которую я нашел наименее болезненной.

-2

Допустим, что Form1 ваша главная форма, и Form2 является тот, который вы хотите открыть: Вы можете использовать этот код (вставьте его в Form1):

Form2 frm = new Form2(); 
frm.Show(); 

Кроме того, если вы хотите, чтобы закрыть вы можете использовать this.Close(); (он закрывает текущую форму). Кроме того, если вы хотите просто открыть Form2, но до сих пор Form1 быть основным, который вы можете использовать:

Form2 frm = new Form2(); 
frm.Show(); 
this.Focus(); 
+0

Это не MVVM. – user3382285

0

Вы можете создать отдельную службу для запуска представления как диалог, так что он может быть использован в общем виде через приложение. И добавит эту услугу в ViewModel через конструктор, который хочет запустить любой диалог.

public interface IDialogWindowService<T> 
{ 
    void Show(); 
    void ShowDialog(); 
} 

public class DialogWindowService<T> : IDialogWindowService<T> where T : Window 
{ 
    public void Show() 
    { 
     container.Resolve<T>().Show(); 
    } 

    public void ShowDialog() 
    { 
     container.Resolve<T>().ShowDialog(); 
    } 
} 

Вы можете создать отдельную службу для запуска представления как диалог, так что он может быть использован в общем виде через приложение. И добавит эту услугу в ViewModel через конструктор, который хочет запустить любой диалог.

public interface IDialogWindowService<T> 
{ 
    void Show(); 
    void ShowDialog(); 
} 

public class DialogWindowService<T> : IDialogWindowService<T> where T : Window 
{ 
    public void Show() 
    { 
     container.Resolve<T>().Show(); 
    } 

    public void ShowDialog() 
    { 
     container.Resolve<T>().ShowDialog(); 
    } 
} 

Теперь просто примените эту услугу к соответствующей модели.

public class YourViewModel 
{ 
    //commands 
    public ICommand someCommand { get; set; } 

    private IDialogWindowService<BookingView> _dialogService; 
    public YourViewModel(IDialogWindowService<YourView > dialogService) 
    { 
     _dialogService = dialogService 
     someCommand = new RelayCommand(someCommandDoJob,() => true); 
    } 

    public void someCommandDoJob(object obj) 
    { 
     //Since you want to launch this view as dialog you can set its datacontext in its own constructor.  
     _dialogService.ShowDialog(); 
    } 
} 

ИЛИ

вы можете использовать DataTemplates, чтобы изменить вид.Это позволяет динамически переключаться Views в зависимости от ViewModel:

<Window> 
    <Window.Resources> 
     <DataTemplate DataType="{x:Type ViewModelA}"> 
     <localControls:ViewAUserControl/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type ViewModelB}"> 
     <localControls:ViewBUserControl/> 
     </DataTemplate> 
    <Window.Resources> 
    <ContentPresenter Content="{Binding CurrentView}"/> 
</Window> 

Если Window.DataContext является экземпляр ViewModelA, то ViewA будет отображаться и

Window.DataContext является экземпляром ViewModelB, то ViewB будет будет отображаться.

Лучший пример, который я когда-либо видел и читал, он сделал Рейчел Лим. See the example.

+0

Вы ссылаетесь на представление в ViewModel: private IDialogWindowService _dialogService; разве это не нарушение MVVM? – whitefang1993

+0

@ whitefang1993 Вы могли бы показать, где я ссылаюсь на представление в viewModel? – StepUp

+0

В классе YourViewModel используется тип «IDialogWindowService » типа _dialogService для типа BookingView. Допустим, у вас есть BookingView в другом проекте, вам не нужно добавлять ссылку на этот проект, чтобы использовать ссылку «IDialogWindowService »? Итак, если у вас есть два проекта: один для ViewModels и один для Views, вы должны передать проект Views в проекте ViewModels, чтобы вы могли использовать BookingView в YourViewModel. Если я что-то неправильно понял, поправьте меня. Я просто пытаюсь прояснить некоторые вещи. – whitefang1993

0
Window newWindow = new Window(); 
Window.Show(); 

или если вы хотите, чтобы отключить предыдущее окно

Window newWindow = new Window(); 
Window.ShowDialog(); 
Смежные вопросы