2013-08-26 84 views
4

確定,XAML是相當簡單的,並且使用MVVM綁定到ICommand SomeCommand { get; }財產上的視圖模型:如果Command綁定解析爲null,爲什麼啓用按鈕?

<Button Command="{Binding Path=SomeCommand}">Something</Button> 

如果SomeCommand回報null,按鈕被啓用。 (與CanExecute(object param)方法無關,因爲沒有實例可以調用該方法)

現在問題:爲什麼按鈕啓用?你將如何處理它?

如果按下「啓用」按鈕,顯然沒有任何東西被調用。這個按鈕看起來好像很難看。

+2

「顯然沒有東西被稱爲」 - 這一點都不明顯。你可能在某處處理'Click'事件,其中按鈕不知道,並且無法知道它會被處理。 – hvd

+0

您看到按鈕上沒有Click事件訂閱。 – wigy

+1

「Click」事件與大多數事件一樣,被路由。包含元素可以處理事件。該按鈕無法知道。 – hvd

回答

6

它已啓用,因爲這是默認狀態。自動禁用它會成爲引發其他問題的任意措施。

如果你想有一個按鈕沒有關聯的命令被禁用,使用適當的轉換器IsEnabled屬性綁定到SomeCommand,如:

[ValueConversion(typeof(object), typeof(bool))] 
public class NullToBooleanConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return value !== null; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 
+0

這正是我所做的。我只是想知道那個「任意措施」是什麼。 – wigy

+0

@wigy:這是一種說法:「爲什麼這是默認行爲?」正如hvd所指出的那樣,如果沒有一個命令並且只是處理點擊事件,是不是公平的遊戲? – Jon

+0

哲學問題是,作爲源的null綁定和根本沒有綁定的綁定是否有區別。我的理解是,如果這兩種情況的處理方式相同,唯一的選擇是在綁定源爲空時啓用按鈕。 – wigy

3

我的同事發現了一個優雅的解決方案:使用綁定後備值!

public class NullCommand : ICommand 
{ 
    private static readonly Lazy<NullCommand> _instance = new Lazy<NullCommand>(() => new NullCommand()); 

    private NullCommand() 
    { 
    } 

    public event EventHandler CanExecuteChanged; 

    public static ICommand Instance 
    { 
     get { return _instance.Value; } 
    } 

    public void Execute(object parameter) 
    { 
     throw new InvalidOperationException("NullCommand cannot be executed"); 
    } 

    public bool CanExecute(object parameter) 
    { 
     return false; 
    } 
} 

然後是XAML的樣子:

<Button Command="{Binding Path=SomeCommand, FallbackValue={x:Static local:NullCommand.Instance}}">Something</Button> 

這種解決方案的優點是,它工作得更好,如果你打破Law of Demeter,你必須在綁定路徑,其中每個實例有可能成爲一些點null

3

與Jon的回答非常相似,您可以使用帶觸發器的樣式來標記在沒有命令集時應禁用的按鈕。

<Style x:Key="CommandButtonStyle" 
     TargetType="Button"> 
    <Style.Triggers> 
     <Trigger Property="Command" 
        Value="{x:Null}"> 
      <Setter Property="IsEnabled" 
        Value="False" /> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

我更喜歡這個解決方案,因爲它直接解決了問題,它不需要任何新的類型。

相關問題