2013-06-28 55 views
1

我有一個用戶控件託管在辦公室Taskpane中,用於Word插件。爲什麼在MultiDataTrigger條件不滿足時,Button.IsEnabled不會啓動爲false或重置爲false?

我試過按照DataTrigger to make WPF Button inactive until TextBox has value的回答和Cleanest way to bind a Button's visibility to the contents of two textboxes的回答,以便在兩個文本框中有非空內容時啓用我的按鈕。

轉換器:

using System.Windows.Data; 
using System.Globalization; 

namespace RetrofitDocumentTool.Converter 
{ 
    [ValueConversion(typeof(String), typeof(Boolean))] 
    class StringToBooleanConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      string val = (string)value; 
      bool result = !string.IsNullOrEmpty(val); 
      return result; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotImplementedException("This converter is oneway only."); 
     } 
    } 
} 

的XAML:

<UserControl 
    ...> 

    <UserControl.Resources> 
     <Style x:Key="ErrorLabel" TargetType="Label"> 
      ... 
     </Style> 

     <Style x:Key="StandardLabel" TargetType="Label"> 
      ... 
     </Style> 

     <Style TargetType="TextBox"> 
      ... 
     </Style> 

     <conv:StringToBooleanConverter x:Key="StringToBoolean"/> 
    </UserControl.Resources> 

    <DockPanel LastChildFill="True"> 
     <Border CornerRadius="8"> 
      <Grid 
       ... 
       ... 
       ... 

       <TextBox 
        Name="Serial_Number" 
        ...> 
       </TextBox> 
       <TextBox 
        Name="Job_Number" 
        ...> 
       </TextBox> 

       <Button 
        ...> 

        <Button.Style> 
         <Style TargetType="{x:Type Button}"> 
          <Style.Triggers> 
           <MultiDataTrigger> 
            <MultiDataTrigger.Conditions> 
             <Condition Binding="{Binding Text, ElementName=Serial_Number, Converter={StaticResource StringToBoolean}}" Value="True"/> 
             <Condition Binding="{Binding Text, ElementName=Job_Number, Converter={StaticResource StringToBoolean}}" Value="True"/> 
            </MultiDataTrigger.Conditions> 
            <Setter Property="IsEnabled" Value="True"/> 
           </MultiDataTrigger> 
          </Style.Triggers> 
         </Style> 
        </Button.Style> 

       </Button> 
      </Grid> 
     </Border> 
    </DockPanel> 

</UserControl> 

問題:

當有東西在文本框中轉換器返回true,如果兩個文本框都有東西這兩個轉換器都會啓動並且應該使用setter。我知道發生這種情況是因爲我可以在設置器中將IsEnabled屬性設置爲False,並且它將停用激活初始狀態的按鈕。

反向做發生:IsEnabled屬性設置爲True不啓用按鈕,其中初始狀態被停用(我做到了通過直接在按鈕的IsEnabled屬性設置爲False)。我認爲這將作爲默認狀態,Setter會覆蓋它。這似乎並非如此。

有些古怪的地方,我注意到:第二個條件似乎

不火,直到第一個廣告。也就是說,如果我在之前輸入一些數據到第二個文本框之前,觸摸第一個文本框,轉換器根本不會觸發。如果我認爲輸入數據到第一個文本框中,兩個轉換器都會啓動。

只有當數據存在於文本框中時,纔有辦法啓用按鈕嗎?我真的需要寫出每種情況的組合:(True/True = Enabled,True/False = Disabled,False/True = Disabled,False/False = Disabled)?這是我的錯誤或一些愚蠢的邏輯錯誤的情況?我目前無法用無偏見的眼光看待這一點。

回答

2

嘗試更新Style

<Style TargetType="{x:Type Button}"> 
    <!-- New Bit --> 
    <Setter Property="IsEnabled" Value="False"/> 
    <!-- End of New Bit --> 
    <Style.Triggers> 
     <MultiDataTrigger> 
      <MultiDataTrigger.Conditions> 
       <Condition Binding="{Binding Text, ElementName=Serial_Number, Converter={StaticResource StringToBoolean}}" Value="True"/> 
       <Condition Binding="{Binding Text, ElementName=Job_Number, Converter={StaticResource StringToBoolean}}" Value="True"/> 
      </MultiDataTrigger.Conditions> 
      <Setter Property="IsEnabled" Value="True"/> 
     </MultiDataTrigger> 
    </Style.Triggers> 
</Style> 

,我做到了通過直接在按鈕

如果設置了元素的屬性IsEnabled屬性設置爲False,那麼WPF優先將會使該屬性的任何Trigger或默認設置器非常不活動。

最後最好總是如果您使用Trigger修改它並確保您沒有該元素本身提到的該屬性,請爲該屬性分配默認值。

在您的具體情況下,您甚至可以在不使用轉換器的情況下執行此操作。

<StackPanel xmlns:sys="clr-namespace:System;assembly=mscorlib"> 
    <TextBox x:Name="tbOne" /> 
    <TextBox x:Name="tbTwo" /> 
    <Button Content="Some Button"> 
    <Button.Style> 
     <Style TargetType="{x:Type Button}"> 
     <Setter Property="IsEnabled" 
       Value="True" /> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ElementName=tbOne, 
              Path=Text}" 
         Value="{x:Static sys:String.Empty}"> 
      <Setter Property="IsEnabled" 
        Value="False" /> 
      </DataTrigger> 
      <DataTrigger Binding="{Binding ElementName=tbTwo, 
              Path=Text}" 
         Value="{x:Static sys:String.Empty}"> 
      <Setter Property="IsEnabled" 
        Value="False" /> 
      </DataTrigger> 
     </Style.Triggers> 
     </Style> 
    </Button.Style> 
    </Button> 
</StackPanel> 
+0

優秀。從來不知道你可以設置一個默認的Setter,很高興知道。你的兩條建議都奏效了,我選擇了後者。謝謝。 – Hydronium

相關問題