【问题标题】:Can't access listbox data template item无法访问列表框数据模板项
【发布时间】:2016-04-12 11:50:25
【问题描述】:

我有这个 XAML 代码,我想访问 AccountNameTextBox 或下面的省略号几行,以便通过在名称旁边添加一些内容来显示列表中的某些帐户已过期(例如 YouTube(已过期) ) 或将椭圆变为红色。问题是我无法访问它们。我试过使用我在这里看到的 VisualTreeHelper 函数 How can I find WPF controls by name or type? 甚至尝试创建一些我自己的但没有任何效果。我注意到的一件事是,当我在 accountListBox 上使用“VirtualTreeHelper.GetChild”时,输出是一个边框控件,它是唯一的孩子。 代码如下。

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

【问题讨论】:

    标签: c# xaml listbox


    【解决方案1】:

    为什么不使用触发器或转换器? 为此,您必须为绑定的项目添加一个属性(我称为我的 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>
    

    然后将您的(过期)TextBlock 添加到 DataTemplate 并绑定到属性

    <TextBlock Text="(Expired)" Visibility="{Binding IsExpired, Converter={StaticResource BooleanToVisibilityConverter}}"/>
    

    对于颜色,您可以使用 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;
    }
    

    此辅助方法查找给定类型的第一个子项。 如果您想按名称查找它,则必须使用名称作为参数而不是泛型类型,并将 (child as T) 检查替换为名称检查。

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

    【讨论】:

    • 非常感谢,今晚我会检查您的解决方案。
    • 我选择了代码方法,因为我已经有了一个静态 Helper 类型的类,它可以很好地融入其中,而且效果很好。如果我可以添加的话,代码也很简洁。
    猜你喜欢
    • 2020-07-11
    • 2016-12-18
    • 2020-06-12
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 2011-11-09
    • 2015-05-11
    • 1970-01-01
    相关资源
    最近更新 更多