如何从子元素条件的父元素DataTrigger

问题描述:

试图找到解决以下问题的方法。如何从子元素条件的父元素DataTrigger

我的目标是: 如果Button中的某个子元素不包含文本,则禁用父按钮。

那么,到底是什么我试图做:

创建一个按钮:

<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> 

现在创建一个风格的触发器:

<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> 

所以,结果我得到: 所有ToggleButtons被禁用。 但我需要只禁用按钮时,属性文本中运行子元素为空

也许我使用根本上错误的方法..感谢您的任何关注。

+0

Tbh,这完全没有意义......为什么你甚至会像这样设计你的按钮?使用按钮的“内容”,并进行自我约束 – lokusking

+0

在我的情况下,我使用按钮内容的几个来源。看起来像:'' –

+0

好吧。对你有好处。不改变它真的很奇怪的事实,这不会工作。样式在**按钮之前定义**,因此对按钮的内容没有任何了解(对于一些简单的文本,您应该真的使用它)。解决方法可能是“ControlTemplate”或“行为”或“代码隐藏”。但是对于普通的XAML,你会有一段糟糕的时光 – lokusking

我建议不要让事情变得复杂。在设置数据之前,样式应用于按钮。直接将VMSource绑定到Button的内容属性。然后,由于加载的文本被更新后才发射使用Loaded事件做一些操作(在这种情况下启用/禁用。见下面剪断。

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

下面将是你Button_Loaded事件。

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

,你总会看到按钮被禁用,因为没有内容。

好运。

哇人... ...你真的得到了我的大脑烟熏。

我来到了一个非常难看的解决方案,那可能会解决你顽固的愿望,使用Run

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> 

转换

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(); 
     } 
    } 

用法

<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

我高度评价!建议您到不使用此解决方案(即使它有效)。 取而代之的是使用按钮的内容,如果你只有纯文本,就把你的东西放在那里。