2016-07-27 9 views
0

Versuchen, Weg zu finden, um das folgende Problem zu lösen.Wie DataTrigger für Parent-Element aus Child-Element-Bedingung

Mein Ziel ist: Wenn ein Kind-Element in Button nicht den Text enthält, dann deaktiviert die Eltern-Schaltfläche.

Also, was genau ich versuche:

Erstellen Sie eine Schaltfläche:

<Button Style="{StaticResource ButtonStyle}" > 
      <TextBlock> 
       <Run Name="TxtElement1" Text=""/> 
      </TextBlock> 
     </Button> 

<Button Style="{StaticResource ButtonStyle}" > 
      <TextBlock> 
       <Run Name="TxtElement2" Text="some text 1"/> 
      </TextBlock> 
     </Button> 

<Button Style="{StaticResource ButtonStyle}" > 
      <TextBlock> 
       <Run Name="TxtElement3" Text="some text 2"/> 
      </TextBlock> 
     </Button> 

nun einen Stil mit Trigger erstellen:

<Style x:Key="ButtonStyle" TargetType="Button"> 
     <Style.Triggers> 
      <DataTrigger Binding="{Binding ElementName=TxtElement1, Path=Text}" Value=""> 
      <Setter Property="IsEnabled" Value="False" /> 
      </DataTrigger> 

      <DataTrigger Binding="{Binding ElementName=TxtElement2, Path=Text}" Value=""> 
      <Setter Property="IsEnabled" Value="False" /> 
      </DataTrigger> 

      <DataTrigger Binding="{Binding ElementName=TxtElement3, Path=Text}" Value=""> 
      <Setter Property="IsEnabled" Value="False" /> 
      </DataTrigger> 
     </Style.Triggers> 
</Style> 

Also, in Folge bekam ich: Alle ToggleButtons sind deaktiviert. Aber ich brauche nur Button deaktivieren, wenn Eigenschaft Text in Run Kind-Element ist leer

Vielleicht bin ich radikal falsch Ansatz verwenden .. Danke für jede Aufmerksamkeit.

+0

Tbh, das macht überhaupt keinen Sinn ... Warum würdest du deine Buttons auch so stylen? Verwenden Sie den Inhalt des Buttons und machen Sie einen selbst bindenden – lokusking

+0

In meinem Fall verwende ich wenige Quelle für den Button Inhalt.Schauen Sie ist wie: ' ' –

+0

Okay. Schön für dich. Ändert nicht die Tatsache, dass es wirklich seltsam ist und dass das nicht funktioniert. Der Style ist ** vor ** Ihren Buttons definiert und hat daher keine Kenntnisse über den Inhalt der Buttons (was Sie eigentlich für einen einfachen Text verwenden sollten). Ein Workaround könnte ein 'ControlTemplate' oder Behavior oder CodeBehind sein. Aber mit Plain XAML wirst du eine schlimme Zeit haben – lokusking

Antwort

0

Ich würde vorschlagen, die Dinge nicht kompliziert zu machen.Stile werden auf die Schaltfläche vor dem Einrichten von Daten angewendet. Binden Sie Ihre VMSource direkt an die Content-Eigenschaft von Button. Verwenden Sie dann Loaded Ereignis einige Operationen (in diesem Fall zu tun aktivieren/deaktivieren. Siehe unten schnippeln.

<Button Loaded="Button_Loaded" Content="" /> 
<Button Loaded="Button_Loaded" Content="some text 1" /> 
<Button Loaded="Button_Loaded" Content="some text 2"/> 

Unten wäre Ihr Button_Loaded Ereignis sein.

private void Button_Loaded(object sender, RoutedEventArgs e) 
{ 
    Button _button = (Button)sender; 
    if (string.IsNullOrEmpty(_button.Content.ToString())) 
     _button.IsEnabled = false; 
} 

Da Loaded nur ausgelöst wird, nachdem Text aktualisiert wird da es deaktiviert, werden Sie immer sehen Taste kein Inhalt.

Good Luck.

0

Wow Mann ... Sie wirklich mein Gehirn smokey bekam.

Ich kam zu einer wirklich hässlichen Lösung, die mit Ihrem hartnäckigen Wunsch umgehen könnte, Run zu verwenden.

XAML

<Style x:Key="ButtonStyle" TargetType="{x:Type Button}"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self} , Path=Content, Converter={StaticResource Converter}, UpdateSourceTrigger=PropertyChanged}" Value="True"> 
        <Setter Property="IsEnabled" Value="False" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 

Converter

public class MyConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      if (value == null) return true; //No Content at all 
      var block = value as TextBlock;    
      if (block != null) 
      { 
       block.Loaded += (sender, args) => //Inlines are only availilable if Control has loaded 
       { 
        var loadedBlock = sender as TextBlock; 
        var inlineCount = loadedBlock.Inlines.Count == 0; 
        if (!inlineCount) 
        { 
         var runs = loadedBlock.Inlines.OfType<Run>(); 
         foreach (var run in runs.Where(run => !string.IsNullOrEmpty(run.Text))) 
         { 
          (loadedBlock.Parent as Button).IsEnabled = true; 
         } 
        } 
       }; 
       return string.IsNullOrEmpty(block.Text); 
      } 
      return false; 
     } 

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

Nutzungs

<Button Content="Click me" Width="80" Height="20" Style="{StaticResource ButtonStyle}"/> 
    <Button Width="80" Height="20" Style="{StaticResource ButtonStyle}"/> 
    <Button Width="80" Height="20" Style="{StaticResource ButtonStyle}"> 
       <TextBlock Foreground="Red"> 
        <Run Name="TxtElement3" Text="some text 2"/> 
       </TextBlock> 
      </Button> 
    <Button Width="80" Height="20" Style="{StaticResource ButtonStyle}" > 
       <TextBlock> 
        <Run Text=""/> 
       </TextBlock> 
      </Button> 
    <Button Width="80" Height="20" Style="{StaticResource ButtonStyle}" > 
       <TextBlock> 
        <Run Text=""/> 
        <Run Text="Some other Text"></Run> 
       </TextBlock> 
      </Button> 

IMPOPRTANT

Ich hoch! Ich empfehle Ihnen NICHT diese Lösung verwenden (auch es funktioniert). Verwenden Sie stattdessen den Inhalt der Schaltfläche und legen Sie Ihre Daten einfach dort ab, wenn Sie nur Text haben.