で完全なパターンメディエーターは、私はMVVMではMVVM
をMediatorパターンに問題を抱えていることはできませんI'lは私の問題をよりよく理解するために、ほぼすべてのクラスを記述します。 I'vはそれのためにメインウィンドウとビューモデルを得た
、それは非常に簡単で、auctually私のUserControlの1を保持しているが、何もしない、メインウィンドウにContentControl.ContentにバインドされViewModelにでUserControlプロパティがあります。
UserControlsは同じです。それぞれのボタンには のボタンが1つしかありません。また、clikcsを処理するコマンドを持つ2つのViewModelがあります。
クラスメディエータはsingletoneであると私は私のViewModel間iteractionのためにそれを使用しようとした
だから、私は何をしようとしていることは内部で彼らと彼らのViewModelを作成していない、ユーザーコントロールを切り替えることですMainWindowViewModel。私はボタンをクリックした後に切り替える必要があります。たとえば、FirstUserControlのボタンをクリックすると、MainWindowのContentControlがSecondUserControlに切り替わります。
probleam iはユーザーコントロールがメディエータNotifyCollegue()関数のパラメータとしてオブジェクト、私は(もちろん、それはMVVMの原理の一つである)それら へのアクセスもを持っていない、それが通るべきUserControlsViewModelsに表示され(例えば、intやstringを渡すなど)問題ではない標準的な型のため、ユーザ型の問題。
私はここ http://www.codeproject.com/Articles/35277/MVVM-Mediator-Pattern
このsolutinを発見したと私はメインウィンドウがContentControlににバインドさ現在のユーザーコントロールを除くすべての明らかになりたいので、なぜ私は、MainWindowViewModelでのUserControlを急がすることはできません。
私は別のsingletoneクラスを作成し、そこにあるすべてのuserControls参照を集めてUserControlsViewModelsの中で使用するか、それとも何か他のものを使うべきでしょうか?
私は自分の問題を明確に記述し、何らかの解決策があることを願っています。
私はどんな質問にも答えてくれることを嬉しく思っており、助けに非常に感謝しています!
ああ、それは本当のアプリではない、私はちょうど
...作成ビューおよびその他のviewmodelsの内側に自分のviewmodelsのViewModelを混合していないではない、のviewmodels間のシステムをmesagingの考え方(概念)を取得したいですもう一度ありがとう!
MAINVIEW
<Window x:Class="TESTPROJECT.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TESTPROJECT"
mc:Ignorable="d"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Title="MainWindow" Height="500" Width="750">
<Grid>
<ContentControl Grid.Row="1" Content="{Binding PagesControl}"/>
</Grid>
MAINVIEWビューモデル
namespace TESTPROJECT
{
class MainWindowViewModel : ViewModelBase
{
private UserControl _pagesControl;
public UserControl PagesControl
{
//Property that switches UserControls
set
{
_pagesControl = value;
OnPropertyChanged();
}
get
{
return _pagesControl;
}
}
public MainWindowViewModel()
{
//Method that will be listening all the changes from UserControls ViewModels
Mediator.Instance.Register(
(object obj) =>
{
PagesControl = obj as UserControl;
}, ViewModelMessages.UserWroteSomething);
}
}
}
FirstUserControl
<UserControl x:Class="TESTPROJECT.FirstUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:TESTPROJECT"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Button Command="{Binding GetCommand}">
hello, i'm first user control!
</Button>
</Grid>
FirstUserControlビューモデル
namespace TESTPROJECT
{
class FirstUserControlViewModel : ViewModelBase
{
//command that is binded to button
private DelegateCommand getCommand;
public ICommand GetCommand
{
get
{
if (getCommand == null)
getCommand = new DelegateCommand(param => this.func(param), null);
return getCommand;
}
}
//method that will handle button click, and in it i'm sending a message
//to MainWindowViewModel throug Mediator class
//and that is allso a problem place because in theory i should
//pass the opposite UserControl object , but from here i have no
//acces to it
private void func(object obj)
{
Mediator.Instance.NotifyColleagues(
ViewModelMessages.UserWroteSomething,
"PROBLEM PLACE");
}
}
}
SecondUserControl
<UserControl x:Class="TESTPROJECT.SecondUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:TESTPROJECT"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Button Command="{Binding GetCommand}">
Hello, i'm second user control!
</Button>
</Grid>
SecondUserControlビューモデル
namespace TESTPROJECT
{
class SecondUserControlViewModel : ViewModelBase
{
//command that is binded to button
private DelegateCommand getCommand;
public ICommand GetCommand
{
get
{
if (getCommand == null)
getCommand = new DelegateCommand(param => this.func(param), null);
return getCommand;
}
}
//method that will handle button click, and in it i'm sending a message
//to MainWindowViewModel throug Mediator class
//and that is allso a problem place because in theory i should
//pass the opposite UserControl object , but from here i have no
//acces to it
private void func(object obj)
{
Mediator.Instance.NotifyColleagues(
ViewModelMessages.UserWroteSomething,
"PROBLEM PLACE");
}
}
}
クラスメディエータ と 列挙ViewModelMessages
namespace TESTPROJECT
{
//this enum holding some kind of event names fro example UserWroteSomething
// is a name of switching one UserControl to another
public enum ViewModelMessages { UserWroteSomething = 1 };
class Mediator
{
//Singletone part
private static Mediator instance;
public static Mediator Instance
{
get
{
if (instance == null)
instance = new Mediator();
return instance;
}
}
private Mediator() { }
//Singletone part
//collection listeners that holds event names and handler functions
List<KeyValuePair<ViewModelMessages, Action<Object>>> internalList =
new List<KeyValuePair<ViewModelMessages, Action<Object>>>();
//new listener registration
public void Register(Action<object> callBack, ViewModelMessages message)
{
internalList.Add(
new KeyValuePair<ViewModelMessages, Action<Object>>(message, callBack));
}
// notifying all the listener about some changes
// and those whose names fits will react
public void NotifyColleagues(ViewModelMessages message, object args)
{
foreach(KeyValuePair<ViewModelMessages, Action<Object>> KwP in internalList)
if(KwP.Key == message)
KwP.Value(args);
}
}
}
アプリケーションの出発点は、
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
FirstUserControl first = new FirstUserControl() { DataContext = new FirstUserControlViewModel() };
SecondUserControl second = new SecondUserControl() { DataContext = new SecondUserControlViewModel() };
new MainWindow()
{
DataContext = new MainWindowViewModel() { PagesControl = first }
}.ShowDialog();
}
}
申し訳ありませんが、私はプログラミングとwpf、mvvmで新しいです。私はちょうど "どのビュー - ビューモデルの組み合わせのための工場"なのか分かりません、私に説明してください、リンクを教えてください?また、あなたの例からviewModelFactoriesがどこに来たのか、MainWindowViewModelをMediatorクラスの中に入れたのはなぜですか? – kotki
さて、オブジェクト指向プログラミングでは、通常、SOLIDの原則と呼ばれる5つの原則に従います。これらは、相互作用して形成する比較的小さな機能(さまざまな問題を解決するのに適した)一貫性のある作業全体。そして、これは "Composition Root"というコンストラクトにつながり、必要なすべてのオブジェクトをインスタンス化し、それらをまとめます(LEGOのように考える)。私のYouTubeチャンネル用に作ったビデオシリーズをチェックしてください:https://www.youtube.com/watch?v=cF7WRPKm8-A&index=1&list=PLIMrZfX3DMVFM_8EgFXmfVhOUNfMvXLLt – feO2x
これは基本的にメディエーターがmainWindowViewModelへの参照を持っている理由です現在アクティブなビューを保持して表示する場合、前者はビューをインスタンス化してモデルを表示し、他のビューモデルから引数を渡すことができます。これらのオブジェクトは、一連のファクトリとともに、「別のビューにナビゲートする」という問題を解決します。 – feO2x