使用的ICommand爲消息模式
這個解決方案針對 分離關注的和單一職責原則
它可以讓你跳過MVVM的RelayCommand模式。
如果您使用XAML,則可以引用具有單個命令類的命名空間。像這樣:
xmlns:cmd="clr-namespace:MyProject"
然後全局或本地風格可以定義爲如下所示。這使得所有按鈕只使用一個傳遞按鈕文本中的命令作爲參數。大多數按鈕使用文本作爲上下文,但標籤也可以使用。
<Style BasedOn="{StaticResource XDButton}" TargetType="{x:Type Button}">
<Setter Property="Command" Value="{StaticResource ResourceKey=cmd}"/>
<Setter Property="CommandParameter" Value="{Binding Content, RelativeSource={RelativeSource Self}}"/>
</Style>
您可以像這樣爲整個項目創建一個命令,注意'路由'基於按鈕文本。的青睞命名約定優於配置「
public class Commands : ICommand
{
private bool canExecute = true;
public bool CanExecute(object parameter)
{
return canExecute;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
NotifyCanExecute(false);
var information = parameter.ToString();
try
{
if (information == "Show Passed") Events.ShowAllPassedTests(this, new EventArgs());
if (information == "Show Failed") Events.ShowAllFailedTests(this, new EventArgs());
if (information == "Sort By elapsed Time") Events.SortByElapsedTime(this, new EventArgs());
if (information == "Sort By Run Data") Events.SortByRunData(this, new EventArgs());
if (information == "Sort By Title") Events.SortByTitle(this, new EventArgs());
if (information == "Generate HTML Report") Events.GenerateHTMLReport(this, new EventArgs());
}
catch (NullReferenceException nre) {
Trace.WriteLine("Test Runner Commands 320- An attempt to fire an event failed due to no subscribers");
}
NotifyCanExecute(true);
}
private void NotifyCanExecute(bool p)
{
canExecute = p;
if (CanExecuteChanged != null) CanExecuteChanged(this, new EventArgs());
}
}
創建一個單一的活動聚集類是這樣的:
public class Events
{
public static EventHandler ShowAllPassedTests;
public static EventHandler ShowAllFailedTests;
public static EventHandler ClearAllFilters;
public static EventHandler SortByElapsedTime;
public static EventHandler SortByRunData;
public static EventHandler SortByTitle;
public static EventHandler GenerateHTMLReport;
public static EventHandler<CheckBox> ColumnViewChanged;
}
您可以創建一個有按鈕這樣的分離型導航儀的用戶控制。當按鈕被點擊時,它只是調用通過Button上下文的Command類。
<StackPanel Orientation="Vertical">
<StackPanel.Resources>
<Style BasedOn="{StaticResource XDButton}" TargetType="{x:Type Button}">
<Setter Property="Command" Value="{StaticResource ResourceKey=cmd}"/>
<Setter Property="CommandParameter" Value="{Binding Content, RelativeSource={RelativeSource Self}}"/>
</Style>
</StackPanel.Resources>
<Button x:Name="XBTNShowPassed" >Show Passed</Button>
<Button x:Name="XBTNShowFailed" >Show Failed</Button>
<Button x:Name="XBTNShowAll" >Show All</Button>
<Button x:Name="XBTNSortByElapsedTime" >Sort by Elapsed Time</Button>
<Button x:Name="XBTNSortByRunData" >Sort By Run Data</Button>
<Button x:Name="XBTNSortByTitle" >Sort By Title</Button>
<Button x:Name="XBTNGenerateHTMLReport" >Generate HTML Report</Button>
</StackPanel>
最後接收視圖模型或其他類看起來是這樣的:
Events.ColumnViewChanged += OnColumnViewChanged;
Events.SortByTitle += OnSortByTitle;
Events.SortByRunData += OnSortByRunData;
Events.SortByElapsedTime += OnSortByElapsedTime;
Events.GenerateHTMLReport += OnGenerateHTMLReport;
Events.ShowAllFailedTests += OnShowAllFailedTests;
Events.ShowAllPassedTests += OnShowAllPassedTests;
}
private void OnShowAllPassedTests(object sender, EventArgs e)
{
FilterCVS(tr => tr.DidTestPass);
}
private void OnShowAllFailedTests(object sender, EventArgs e)
{
FilterCVS(tr => tr.DidTestFail);
}
不要忘記實現Dispose
當代碼掛接到事件處理程序變得沒有資格垃圾採集。爲了解決這個問題,實現Dispose模式和斷開事件處理器...如
Events.OnColumnViewChanged -= OnColumnViewChanged;
如果您唯一關心的是可視性,您可以將它們抽象爲部分類。但是,如果你需要很多命令,這可能暗示你的ViewModel嘗試做太多。請記住,上面的解決方案可能會破壞你的viewmodels封裝,因爲上述命令只能訪問公共屬性和方法 – Tseng
你能提供一些更具體的哪些類型的命令嗎?如果您嘗試在ViewModel中投入太多關注點,或者您需要更好的抽象 – Tseng