2012-05-02 56 views
2

我創建了一些具有綁定能力的「ClearCommand」ICommand依賴項屬性的自定義控件(而不是UserControls)。這個屬性將完成它的聲音:它將清除控件中的所有值(文本框等)。我也將這些相同的屬性(一些)綁定到我在下面描述的VM。使用MVVM從WPF中的ViewModel觸發命令

現在我被困試圖觸發ClearCommand在這些控制在下面的MVVM場景:

我已經添加了幾個這樣的控件進入我的視野。該視圖還包含一個「保存」按鈕,該按鈕綁定到我的ViewModel的屬性SaveCommandDelegateCommand屬性。

我需要做的是,成功保存後,虛擬機應該觸發視圖中找到的那些控件上的ClearCommandenter image description here

UPDATE

我已經添加下面的代碼示例。我有幾個類似於ExampleCustomControl的控件。另外,請注意,如果完全關閉,我可以重新組織這些內容。

實例的控制代碼段:

public class ExampleCustomControl : Control { 

    public string SearchTextBox { get; set; } 
    public IEnumerable<CustomObject> ResultList { get; set; } 

    public ExampleCustomControl() { 
     ClearCommand = new DelegateCommand(Clear); 
    } 

    /// <summary> 
    /// Dependency Property for Datagrid ItemSource. 
    /// </summary> 
    public static DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", 
     typeof(CustomObject), typeof(ExampleCustomControl), new PropertyMetadata(default(CustomObject))); 

    public CustomObject SelectedItem { 
     get { return (CustomObject)GetValue(SelectedCustomObjectProperty); } 
     set { SetValue(SelectedCustomObjectProperty, value); } 
    } 

    public static DependencyProperty ClearCommandProperty = DependencyProperty.Register("ClearCommand", typeof(ICommand), 
      typeof(ExampleCustomControl), new PropertyMetadata(default(ICommand))); 

    /// <summary> 
    /// Dependency Property for resetting the control 
    /// </summary> 
    [Description("The command that clears the control"), Category("Common Properties")] 
    public ICommand ClearCommand { 
     get { return (ICommand)GetValue(ClearCommandProperty); } 
     set { SetValue(ClearCommandProperty, value); } 
    } 

    public void Clear(object o) { 
     SearchTextBox = string.Empty; 
     SelectedItem = null; 
     ResultList = null; 
    } 
} 

示例View片段:

<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*" /> 
     <RowDefinition Height="30"/> 
    </Grid.RowDefinitions> 
    <control:ExampleCustomControl Grid.Row="0" 
     SelectedItem="{Binding Selection, UpdateSourceTrigger=PropertyChanged}" /> 
    <Button Grid.Row="1" x:Name="ResetButton" Command="{Binding SaveCommand}"> 
     Save 
    </Button> 
</Grid> 

例視圖模型:

public class TestViewModel : WorkspaceTask { 
    public TestViewModel() { 
     View = new TestView { Model = this }; 
     SaveCommand = new DelegateCommand(Save); 
    } 

    private CustomObject _selection; 
    public CustomObject Selection { 
     get { return _selection; } 
     set { 
      _selection = value; 
      OnPropertyChanged("Selection"); 
     } 
    } 

    public DelegateCommand SaveCommand { get; private set; } 
    private void Save(object o) { 
     // perform save 
     // clear controls 
    } 
} 
+0

通常情況下,我的命令是在我的視圖模型。從ViewModel,你可以調用'MyCommand.Execute();'。如果這不是你的項目的結構,請張貼一些代碼來澄清。 – cadrell0

+0

作爲一個快速的解決方法,當你註冊SelectedIOtemProperty和回調,有你想要的一切清楚你可以設置PropertyChangedCallback在PropertyMetadata。不過,我會建議你考慮重構你的設置,並將所有綁定屬性與虛擬機一起清除。 – HAdes

+0

將所有ExampleCustomControl的屬性綁定到視圖模型的問題將重用。我希望搜索邏輯/等坐在自定義控件中,我希望能夠在幾個不同的視圖中重用相同的控件。 – Alex

回答

2

正如其他人所說的,虛擬機不應該直接在MVVM中瞭解視圖,所以虛擬機在您的自定義控件上觸發某些內容以清除所有內容並不合理。

我會將自定義控件的DataContext設置爲具有所有要清除的屬性的對象,這些屬性都與文本框等綁定(雙向)等。然後在Save()方法中,您可以設置一個新對象(自定義控件DataContext被綁定到該對象),並且所有屬性都將被清除(假設您已在對象上實現了INotifyPropertyChanged)。

更新:

按我的意見,請參閱您的當前設置(未經測試的BTW)解決方法的一個例子:

public static DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", 
     typeof(CustomObject), typeof(ExampleCustomControl), new PropertyMetadata(default(CustomObject), OnSelectedItemChanged)); 


    private static void OnSelectedItemChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     var cont = source as ExampleCustomControl; 

      //do all the clearing of txtboxes etc here.... 
     cont.SearchTextBox = string.Empty; 
    } 

但我仍然會嘗試並移動到所有這些虛擬機。即有明確的命令,就像你做save​​命令和文本文字等綁定到虛擬機的屬性,當調用的命令它清除一切,然後你就可以很容易地從保存的方法在虛擬機中也呼籲。但顯然我不知道你長期努力實現什麼,或者選擇的項目和文本框等是如何相關的,所以我依賴(一如既往)。

+0

由於SearchTextBox不是靜態類型,建議的解決方案將不起作用。 – Alex

+1

沒有,如果你使用的DependencyObject和投回到你ExampleCustomControl,看到我的更新答案 – HAdes

+0

我將如何實現ExampleCustomControl作爲視圖/視圖模型,這樣我可以重新使用控制(和所包含的搜索功能),方便地將其綁定到SelectedItem從我的TestViewModel內? – Alex

1

這聽起來像你正在思考這個錯誤的方式。在MVVM中,ViewModel永遠不應該知道任何有關自定義控件的知識(因此,您在使用此Clear功能時遇到問題)。

你的要求是有點模糊,但你有沒有考慮:

1)如果屬性是從VM的約束,無法控制檢測時,這些變化? 2)如果您確實需要從XAML層調用Clear並希望保持純MVVM,請考慮類似Expression Blend SDK的CallMethodAction

+0

關於#1:我已經考慮過這種情況。自定義控件包含搜索文本框和數據網格以顯示結果。所有搜索的邏輯都包含在控制實現本身內。控件的datagrid的選定值實際上是我在VM中綁定的依賴屬性。雖然我可以從我的VM中重置選定的值,但是如何觸發自定義控件中其餘控件的重置? – Alex

+1

亞歷克斯 - 我認爲你需要發佈一些減少示例代碼,以獲得進一步的幫助。沒有什麼比一個代碼示例。 – RichardOD

+0

讓我遵循了通過聲明,雖然我可能會引發從DependencyProperty的一個事件,該事件將被包含在一個靜態的範圍。這不起作用重置控件的非靜態範圍的屬性。 – Alex

0

作爲我的評論的後續。我懷疑你的命令是直接針對視圖並清除TextBox es。相反,讓您的命令定位ViewModel並清除View所綁定的屬性。然後,您可以將該命令作爲ViewModel上的一個屬性,並在需要時調用它。

相關問題