2014-09-26 20 views
0

我有一個DropDownView其中包含一個DropDownList如下無法解析使者的不確定性多的ViewModels

<ComboBox Grid.Column="1" ItemsSource="{Binding Path=MyList}" 
      SelectedItem="{Binding Path=Item}" Height="30"/> 

DropDownViewModel有2個屬性如下

private ObservableCollection<string> _myList; 
public ObservableCollection<string> MyList { 
    get { return _myList; } 
    set { 
     if (_myList == value) 
      return; 

     _myList = value; 
     RaisePropertyChanged("MyList"); 
    } 
} 

private string _item; 
public string Item { 
    get { return _item; } 
    set { 
     if (_item == value) 
      return; 

     _item = value; 
     Messenger.Default.Send(_item); //line1 
     RaisePropertyChanged("Item"); 
    } 
} 

現在,我有多個的ViewModels這創建如下DropdownViewModel的多個實例。每個ViewModel都屬於一個獨立的視圖,並且不會相互關聯。 (爲了簡單起見只考慮2視圖模型創建。)

ViewModel1

public class ViewModel1 
{ 
    private readonly DropDownViewModel _ddVM1; 
    public ViewModel1(){ 
     _ddVM1 = new DropDownViewModel(); 
     Messenger.Default.Register<string>(this, this.GetItem1); 
    } 

    private void string GetItem1(string obj){ 
     //perform some function 
    } 

} 

ViewModel2

public class ViewModel2 
{ 
    private readonly DropDownViewModel _ddVM2; 
    public ViewModel2(){ 
     _ddVM2 = new DropDownViewModel(); 
     Messenger.Default.Register<string>(this, this.GetItem2); 
    } 

    void string GetItem2(string obj){ 
     //perform some function 
    } 
} 

現在,當我運行該應用程序,並從任一項的DropDownList選擇一個值查看時,總是調用第一個註冊的函數(在這種情況下爲GetItem1)。我只用一個Messenger.Default.Register測試了代碼,只有一個ViewModel,並且該應用運行良好。我還測試了代碼是否正在創建多個實例DropDownViewDropDownViewModel。在這方面似乎也沒有問題。

我不明白爲什麼這種情況發生在多於一個ViewModel的情況下,因爲每個ViewModel都有自己的DropDownViewDropDownViewModel實例。那麼內部究竟發生了什麼?爲什麼在line1上創建了多個DropDownViewModel實例時,該應用會以怪異的方式運行?如何解決這個問題?

+0

附註:你確定你的問題與ASP.Net有關嗎?如果沒有 - 刪除標籤。同時考慮刪除帖子中的謝謝文字。 – 2014-09-26 06:12:25

回答

1

在我看來,這個問題是不是WPF MVVM相關,但與此相關的代碼:

Messenger.Default.Send(_item); //line1 

的問題是,Messenger.Default在我看來就像一個靜態類和這個靜態默認信使不會改變。這是對的嗎?我無法在您的機器上進行調試,但這在我看來是一種代碼味道。

作爲一個方面說明,您應該可以切換並更改視圖模型而不會出現問題。要解決您的設計問題,請在視圖模型內添加您的messenger實例,以免共享全局狀態。

「爲什麼在創建DropDownViewModel的多個實例時,該應用會凍結在line1上?」

很可能與WPF代碼無關,但又與Messenger.Default.Send方法代碼相關。

爲了您暴食的代碼,你可以不寫:「路徑」只是:

<ComboBox Grid.Column="1" ItemsSource="{Binding MyList}" 
     SelectedItem="{Binding Item}" Height="30"/> 

,它應該在我所知道的所有情況。

+0

我不認爲{Binding PropertyName}和{Binding Path = PropertyName}有任何區別。 – SohamC 2014-09-26 06:49:10

+0

是的,這是評論的意見:) – 2014-09-26 06:50:14

+0

@ user1603970:只是想知道,這是如何解決你的問題? – 2014-09-26 08:29:00

0

我想這是你正在使用的MVVMLight。在Messenger中的決定性因素就知道發送消息給收件人,是TMessage,消息的類型:

public virtual void Register<TMessage>(object recipient, Action<TMessage> action) 
伴您行

所以

Messenger.Default.Register<string>(this, this.GetItem1); 

視圖模型現在收到任何消息字符串類型。發送字符串類型消息時,兩種方法(GetItem1GetItem2)都會執行。

正常情況是,你必須爲每個消息的複雜類型,所以你可以使用這樣的事情,與DropDownId鏡像附加到每個DropDownViewModel一個唯一的標識符。

public class DropDownSelectedItemMessage 
{ 
    public string DropDownId { get; set; } 
    public string SelectedItem { get; set; } 
} 

那麼你還是這樣註冊

Messenger.Default.Register<DropDownSelectedItemMessage>(this, this.GetItem1); 

發送消息

Messenger.Default.Send(new DropDownSelectedItemMessage() { DropDownId = _id, SelectedItem = _item }); 

,並在消息處理程序中,你比較IDS:

private void string GetItem1(DropDownSelectedItemMessage message) 
{ 
    if (message.DropDownId == _ddVM1.Id) 
    { 
     //perform some function 
    } 
} 

然而,我的兩美分:忘掉DropDownView模型(在您的實際ViewModel上保留SelectedItem和ItemsSource屬性),完全避免使用Mediator模式。引入一個實現並處理INotifyPropertyChanged的基類,以便您可以再次在一行上編寫屬性。我使用的是Here