2013-05-08 44 views
0

希望這個問題不是太籠統,但是我剛開始使用WPF,而且我對此感到頭痛。使用MVVM動態創建UI控件的上下文菜單命令

我正在開發一個使用動態創建控件的應用程序。然而,目前我無法弄清楚如何使命令創建並向當前窗口添加更多控件,因爲這些命令僅在ViewModel中創建時無法看到視圖。但是我無法將所有內容都保存在XAML中,因爲除了一些最初爲空的堆棧面板之外的所有控件都是動態的。儘管如此,我覺得我很想念一些簡單的東西。

所以我在這裏有約束力

<MenuItem Header="LabelMenuItem" Command="{Binding Path=SpawnLabel}"/> 

在這裏,我有命令

public ICommand SpawnLabel { get { return new DelegateCommand(OnSpawnLabel); } } 

委託命令類似於這裏定義的繼電器命令。

public class DelegateCommand : ICommand 
    { 
     private readonly Action _command; 
     private readonly Func<bool> _canExecute; 
     public event EventHandler CanExecuteChanged 
     { 
      add { CommandManager.RequerySuggested += value; } 


     remove { CommandManager.RequerySuggested -= value; } 
    } 

    public DelegateCommand(Action command, Func<bool> canExecute = null) 
    { 
     if (command == null) 
      throw new ArgumentNullException(); 
     _canExecute = canExecute; 
     _command = command; 
    } 

    public void Execute(object parameter) 
    { 
     _command(); 
    } 

    public bool CanExecute(object parameter) 
    { 
     return _canExecute == null || _canExecute(); 
    } 

} 

這個作品在視圖模型,但我無法弄清楚如何在地球上,以使其在視圖中工作(或傾訴的觀點沒有打破MVVM原則),這樣我就可以使用真正改變UI當前在c#中創建的控件。

目前,當我這樣做時,我得到一個BindingExpression路徑錯誤,這是有道理的,但我無法弄清楚如何綁定它在視圖中查找命令。

回答

0

你間接地與UI通過事件進行通信,如果你改變你開除PropertyChanged的屬性,UI將更新的綁定,如果你改變一個集合你火CollectionChanged,並增加了新的控制或舊的清除。

的重要接口INotifyPropertyChangedINotifyCollectionChanged,只需綁定一個ItemsControl(通過ItemsSource)在您的視圖模型的ObservableCollection<T>並添加到集合中的命令(您可能需要使用ItemsControl.ItemTemplate指定查看您視圖模型,取決於你使用的MVVM框架)。

+0

所以我會在ViewModel中執行命令代碼,然後onExecute會觸發在視圖中觸發的CollectionChanged,然後我可以添加新的UI元素? – Smeasum 2013-05-08 21:54:17

+0

@Smeasum:不,您只需向ObservableCollection中添加一個項目,然後在內部啓動該事件,其中ItemsControl將創建指定爲ItemTemplate的內容或者爲[隱式指定的項目類型](http://stackoverflow.com/questions/5644392/conditional-list-itemtemplate-or-datatemplate-in-wpf/5644414#5644414)。如果您搜索SO或網絡,有很多這樣的例子,另見[MSDN](http://msdn.microsoft.com/en-us/library/ms752347.aspx#binding_to_collections)。 – 2013-05-08 22:08:00