請問如何是否能解決這個程式要多個View去共享一個ViewModel的辦法?
目前這個程式的View架構如下:
MainWindow.xaml (window)
|__ReviewView.xaml (page)
|__DisplayControlView.xaml (page)
|__DisplayPanelView.xaml (page)
|__DisplayView.xaml (page)

ReviewView.xaml用frame容器包含DisplayControlView.xaml跟DisplayPanelView.xaml兩個Page
DisplayPanelView.xaml又往下包含了一個DisplayView.xaml
主要功能是-在DisplayControlView上有按鈕可以開啟圖檔,然後顯示在DisplayView上

目前找過文章說可以View設定DataContext綁定ViewModel,或是反過來,但是都沒很完整的範例示範,還請各位大大能幫幫忙!謝謝!

我試過用Singleton修改過,結果越改越糟糕........囧

以下是我原始的程式片段:
--DisplayControlView.xaml

<Page.DataContext>
    <vm:DisplayViewModel/>
</Page.DataContext>
<Button x:Name="btnDpOpen" Style="{DynamicResource ButtonStyle}" Width="120" Command="{Binding OpenFile}">

--DisplayView.xaml

<Page.DataContext>
    <vm:DisplayViewModel/>
</Page.DataContext>
<Image x:Name="imgDisplayView" Source="{Binding ImagePath}">
	<Image.RenderTransform>
		<TransformGroup>
			<TranslateTransform/>
			<RotateTransform/>
			<ScaleTransform/>
		</TransformGroup>
	</Image.RenderTransform>
</Image>

--DisplayViewModel.cs

class DisplayViewModel : ViewModelBase
	private DisplayImageModel image { get; set; }
	private ObservableCollection<DisplayImageModel> imagelist = new ObservableCollection<DisplayImageModel>();
	public ObservableCollection<DisplayImageModel> ImageList
		get { return imagelist; }
			imagelist = value;
			OnPropertyChanged();
	public string ImagePath
		get { return image.Path; }
			if (image.Path != value)
				image.Path = value;
				OnPropertyChanged();
	public DisplayViewModel()
		image = new DisplayImageModel();
		ImagePath = @"C:\lenna.png";
	public bool CanExecute()
		return true;
	public RelayCommand OpenFile
		get { return new RelayCommand(openFile, CanExecute); }
	private void openFile()
		string[] picExtName = new string[] { ".PNG", ".JPG", "JEPG", "BMP" };
		OpenFileDialog dlgOpenFile = new OpenFileDialog() 
		{ Filter = "Picture|*.jpg;*.jpeg;*.bmp;*.png|All File|*.*" };
		if (dlgOpenFile.ShowDialog() != true)
			return;
		if (picExtName.Any(System.IO.Path.GetExtension(dlgOpenFile.FileName).ToUpper().Contains))
			ImagePath = dlgOpenFile.FileName;
			OnPropertyChanged();

--ViewModelBase.cs

public abstract class ViewModelBase : INotifyPropertyChanged
	public event PropertyChangedEventHandler PropertyChanged;
	public void SetValue<T>(ref T property, T value, [CallerMemberName] string propertyName = null)
		if (property != null)
			if (property.Equals(value))
				return;
		property = value;
		OnPropertyChanged(propertyName);
	protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
		if (PropertyChanged != null)
			PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

--RelayCommond.cs

public class RelayCommand : ICommand
	readonly Func<bool> _canExecute;
	readonly Action _execute;
	public RelayCommand(Action execute) : this(execute, null)
	public RelayCommand(Action execute, Func<bool> canExecute)
		_execute = execute ?? throw new ArgumentNullException("execute");
		_canExecute = canExecute;
	public event EventHandler CanExecuteChanged
			if (_canExecute != null) CommandManager.RequerySuggested += value;
		remove
			if (_canExecute != null) CommandManager.RequerySuggested += value;
	[DebuggerStepThrough]
	public bool CanExecute(object parameter)
		return _canExecute == null ? true : _canExecute();
	public void Execute(object parameter)
		_execute();
                            

Xaml? WPF喔.
多個View共用一個ViewModel,
有甚麼問題嗎?

private DisplayViewModel viewModel = new DisplayViewModel();

在建構子的地方加入,

DataContext = viewModel;

但是你的DisplayViewModel沒有宣告public可能無法共用.

DisplayControlView開啟的影像無法在DisplayView顯示出來
還是有可以提供的關鍵字或範例參考?
我理解是缺省public private protected時,應該是設定public的
我是有嘗試在建構子裡故意給一個影像路徑預設值
發現都會顯示預設的這個影像,所以猜是開的檔案路徑字串沒正確傳給另一個View,應該Notify也只作用在自己的View上

只是要改成同一個instance,沒什麼頭緒

我嘗試全寫在一起這MVVM模式是正確的,但實際上需要模組化才能重複應用DisplayView才分開的
正常使用上也不太是只開一個影像檔,除非是交學校作業 XD

網上搜到是還有用Event傳遞,但我的DisplayView跟DisplayControlView並不在Logical Tree/Visual Tree的直接上下關係,就比較麻煩

對了,大大的辦法不就等同在xaml內的

<Page.DataContext>
    <vm:DisplayViewModel/>
</Page.DataContext>

只差在寫在.cs或是.xaml而已吧?
另外也要『正確』觸發OnPropertyChanged去通知UI更新才行
這也是要解的問題啊!

正常使用上也不太是只開一個影像檔,除非是交學校作業 XD 網上搜到是還有用Event傳遞,但我的DisplayView跟DisplayControlView並不在Logical Tree/Visual Tree的直接上下關係,就比較麻煩 對了,大大的辦法不就等同在xaml內的 <Page.DataContext> <vm:DisplayViewModel/> </Page.DataContext> 只差在寫在.cs或是.xaml而已吧? 另外也要『正確』觸發OnPropertyChanged去通知UI更新才行 這也是要解的問題啊!

大大說的方法有範例嗎?看大大是WPF大師呢,應該MVVM也熟的~^^
基本上,上述問題中就說instance不是同一個,所以兩個View各自為政
嘗試Singleton Pattern改過,DisplayView也沒成功收到字串
也試過在兩者的根結點上的ReviewView去設定過DataContext也是無法把字串傳過去,DisplayView的影像還是出不來

所以想問說,MVVM下如何將ViewModel實例化instance是固定一個給數個View使用的

如果方法不拘的話,
WinForm跟WPF其實都可以寫共用的類別跟共用的函式,
讀取或修改的時候直接去改它們就可以,
跟你在哪個檔案裡面沒有關係.

如果你一定要用同一個ViewModel的話,
或許在MainWindow新增一個static的ViewModel試試看,
(不用static設成public也是可以,
但是你就需要一直傳遞MainWindow物件)
然後DataContext就不要寫在Xaml了,
就寫在後端吧.

我是沒有這樣子做過,
不過似乎是可行的.

經過幾天嘗試,目前是用Singleton Pattern勉強符合像MVVM的樣子
對Pure MVVM方法還努力中,有些不甚滿意/images/emoticon/emoticon36.gif
目標是.xaml.cs內的程式碼清空啊!!!!
####DisplayViewModel.cs

加入Double-Checking Lock SingleTon
改建構子修飾詞限制為private

private static readonly object padlock = new object();
private static volatile DisplayViewModel _instance = null;
public static DisplayViewModel Instance
		if (_instance == null)
			lock (padlock)
				if (_instance == null)
					_instance = new DisplayViewModel();
		return _instance;
private static DisplayImageModel image { get; set; }

####DisplayView.xaml & DisplayControlView.xaml

刪除以下的DataContext引用

<Page.DataContext>
    <vm:DisplayViewModel/>
</Page.DataContext>

####DisplayView.xaml.cs & DisplayControlView.xaml.cs

在初始化元件後設定DataContext為Singleton ViewModel

InitializeComponent();
this.DataContext = DisplayViewModel.Instance;