我有这个XAML代码,我想访问下面的AccountNameTextBox或elipse几行,以便通过在名称旁边添加一些内容来显示列表中的某些帐户已过期(例如,YouTube(已过期)) )或通过将椭圆变成红色。问题是我无法访问它们。我尝试过使用我在这里看到的VisualTreeHelper函数 How can I find WPF controls by name or type?甚至尝试创造我自己的一些但没有任何作品。我注意到的一件事是当我使用" VirtualTreeHelper.GetChild"在accountListBox上,输出是一个边框控件,它是唯一的子节点。 代码如下。
`<StackPanel x:Name="MainStackPanel" Grid.Row="1" Grid.RowSpan="2" DataContext="{StaticResource ResourceKey=accountManager}">
<ListBox x:Name="accountListBox" ItemsSource="{Binding LoadedAccounts}" Height="600" VerticalAlignment="Bottom" Margin="10,10" Background="Transparent" DoubleTapped="accountListBox_DoubleTapped" ScrollViewer.VerticalScrollBarVisibility="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10,0,0,0">
<TextBlock x:Name="AccountNameTextBox" Text="{Binding AccountName}" FontFamily="Segoe Script" FontSize="30" Foreground="White"/>
<StackPanel Orientation="Horizontal">
<StackPanel>
<!--<TextBlock Text="{Binding Username}" FontSize="25" Foreground="Lime"/>-->
<TextBlock Text="{Binding Email}" FontStyle="Italic" FontSize="25" Foreground="DarkSeaGreen"/>
<TextBlock Text="{Binding Password}" FontSize="25" Foreground="YellowGreen"/>
</StackPanel>
<Ellipse x:Name="Elipse" Height="Auto" Width="10" Margin="10,0">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="YellowGreen" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>`
答案 0 :(得分:0)
为什么不使用触发器或转换器? 为此,您必须向绑定项添加一个属性(我称之为我的IsExpired)
然后在DataTemplate中添加DataTrigger:
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsExpired}" Value="True">
<Setter Property="Visibility" Value="Visible" TargetName="ExpiredTextBlock" />
<Setter Property="Fill" Value="Red" TargetName="Elipse" />
</DataTrigger>
</DataTemplate.Triggers>
转换器的一种可能性是将Converter-Resource添加到DataTemplate:
<DataTemplate.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</DataTemplate.Resources>
然后将您的(Expired)TextBlock添加到DataTemplate并绑定到属性
<TextBlock Text="(Expired)" Visibility="{Binding IsExpired, Converter={StaticResource BooleanToVisibilityConverter}}"/>
对于Color,您可以使用BooleanToColorConverter执行相同操作。
如果你想坚持你的代码方法,你必须深入了解你的视觉树:
public static T GetChildOfType<T>(this DependencyObject depObj)
where T : DependencyObject
{
if (depObj == null) return null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = (child as T) ?? GetChildOfType<T>(child);
if (result != null) return result;
}
return null;
}
此辅助方法查找给定类型的第一个子节点。 如果要按名称查找它,则必须使用名称作为参数而不是泛型类型,并使用名称检查替换(子项为T)检查。
我个人的偏好是触发器的解决方案,但这取决于你......