2017-07-19 50 views
0

如何實現3個WPF按鈕共享相同的CanExecute()結果,而無需在ViewModel中添加其他屬性。如何實現3個WPF按鈕以共享相同的CanExecute結果

直接在View中執行這個場景嗎?

按鈕:: A,B,C

如果A命令運行CanExecute爲A,B,C爲假 若B命令運行CanExecute爲A,B,C爲假 如果C命令是運行CanExecute for A,B,C爲假 如果沒有任何命令正在運行CanExecute爲真

+2

「中直接查看」。不,你在視圖模型中實現這個邏輯。將相同的CanExecute謂詞傳遞給所有三個命令。 – mm8

+0

我會反對這種方法(如果可能的話),介紹一個屬性使代碼更具可讀性。 –

+0

@ user1316502:你有沒有聽從我的建議或發生了什麼? – mm8

回答

1

您在視圖模型中實現此邏輯。您可以對所有三個命令使用相同的CanExecute謂詞,但視圖模型必須通過提高每個命令的CanExecuteChanged來跟蹤當前正在執行的命令並刷新命令的狀態。

這是給你一個樣本實現,而其中任何一個正在執行禁用所有命令:

public class ViewModel 
{ 
    public ViewModel() 
    { 
     Func<bool> canExecute =() => !_isAExecuting && !_isBExecuting && !_isCExecuting; 
     CommandA = new RelayCommand(ExecuteA, canExecute); 
     CommandB = new RelayCommand(ExecuteB, canExecute); 
     CommandC = new RelayCommand(ExecuteC, canExecute); 
    } 

    public RelayCommand CommandA { get; } 
    public RelayCommand CommandB { get; } 
    public RelayCommand CommandC { get; } 

    private bool _isAExecuting; 
    private void ExecuteA() 
    { 
     _isAExecuting = true; 
     RefreshCommands(); 
     Task.Factory.StartNew(()=> System.Threading.Thread.Sleep(2000)) 
      .ContinueWith(task => 
      { 
       _isAExecuting = false; 
       RefreshCommands(); 
      }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 
    } 

    private bool _isBExecuting; 
    private void ExecuteB() 
    { 
     _isBExecuting = true; 
     RefreshCommands(); 
     Task.Factory.StartNew(() => System.Threading.Thread.Sleep(3000)) 
      .ContinueWith(task => 
      { 
       _isBExecuting = false; 
       RefreshCommands(); 
      }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 
    } 

    private bool _isCExecuting; 
    private void ExecuteC() 
    { 
     _isCExecuting = true; 
     RefreshCommands(); 
     Task.Factory.StartNew(() => System.Threading.Thread.Sleep(1000)) 
      .ContinueWith(task => 
      { 
       _isCExecuting = false; 
       RefreshCommands(); 
      }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 
    } 

    private void RefreshCommands() 
    { 
     CommandA.RaiseCanExecuteChanged(); 
     CommandB.RaiseCanExecuteChanged(); 
     CommandC.RaiseCanExecuteChanged(); 
    } 
} 

查看:

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfApplication1" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="300" Width="300"> 
    <Window.DataContext> 
     <local:ViewModel /> 
    </Window.DataContext> 
    <StackPanel> 
     <Button Content="A" Command="{Binding CommandA}" /> 
     <Button Content="B" Command="{Binding CommandB}" /> 
     <Button Content="C" Command="{Binding CommandC}" /> 
    </StackPanel> 
</Window> 
相關問題