无法访问列表框数据模板项

时间:2016-04-12 11:50:25

标签: c# xaml listbox

我有这个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>`

1 个答案:

答案 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)检查。

我个人的偏好是触发器的解决方案,但这取决于你......