WPF - VB在列表框中访问控件

时间:2015-06-30 07:37:50

标签: wpf vb.net

我知道有很多这样的帖子,但我已经搜索了几天,似乎没有人能为我找到正确的答案。我有一个包含数据集结果的数据绑定列表框。其中一个结果是十进制百分比,我希望用它来填充每行的单个条形图。我决定最简单的方法(当然)这样做是使用矩形控件并使用数据绑定值来控制其宽度属性...简单!

但是,我真的很难能够从列表框项目中访问矩形控件。以下是我的WPF示例:

<ListBox x:Name="lbResults" HorizontalContentAlignment="Stretch" ItemsSource="{Binding}" HorizontalAlignment="Left" Height="578" Margin="10,64,0,0" VerticalAlignment="Top" Width="754">
            <ListBox.ItemTemplate>
                <DataTemplate>

                    <Border BorderBrush="#FFDEDFFF" Margin="3" Padding="1" BorderThickness="2" CornerRadius="3" Background="#FFF8F8FD" >

                        <StackPanel Orientation="Horizontal">


                            <Border BorderBrush="#FFE2E3FF" Width="200" Margin="3" Padding="1" BorderThickness="2" CornerRadius="3" Background="#FFF3F4FF" >

                                <StackPanel Orientation="Vertical">

                                    <Label Content="{Binding FULLNAME}" FontWeight="Bold" Padding="1"/>

                                    <Label Name="lblPot" Padding="1">
                                        <Label.Content>
                                            <Binding Path="POT"/>
                                        </Label.Content>
                                        <Label.ContentStringFormat>
                                            Pot: {0}
                                        </Label.ContentStringFormat>
                                    </Label>

                                    <Label Padding="1">
                                        <Label.Content>
                                            <Binding Path="POTSTATUS"/>
                                        </Label.Content>
                                        <Label.ContentStringFormat>
                                            Status: {0}
                                        </Label.ContentStringFormat>
                                    </Label>

                                    <Label Padding="1">
                                        <Label.Content>
                                            <Binding Path="DAYSTODAY"/>
                                        </Label.Content>
                                        <Label.ContentStringFormat>
                                            Days: {0}
                                        </Label.ContentStringFormat>
                                    </Label>


                                </StackPanel>

                            </Border>

                            <Border BorderBrush="#FFE2E3FF" Width="295" Margin="3" Padding="5" BorderThickness="2" CornerRadius="3" Background="#FFF3F4FF" >

                                <StackPanel Name="spProgress" Orientation="Vertical">

                                    <Label Content="{Binding Complete}" Padding="1"/>


                                    <Border BorderBrush="#FFE2E3FF"  BorderThickness="1" CornerRadius="5" Height="30" Width="280">

                                        <Rectangle Name="rctProgSuccess" HorizontalAlignment="Left" Height="28" Stroke="{x:Null}" VerticalAlignment="Top" Width="280">
                                            <Rectangle.Fill>
                                                <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                                                    <GradientStop Color="White" Offset="0"/>
                                                    <GradientStop Color="#FF54EE62" Offset="1"/>
                                                </LinearGradientBrush>
                                            </Rectangle.Fill>
                                        </Rectangle>

                                    </Border>

                                </StackPanel>

                            </Border>


                        </StackPanel>

                    </Border>

                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

我尝试了各种方法来在代码后面访问这个矩形控件,以便将其宽度值进行操作,但到目前为止都失败了。我最近的尝试看起来像:

        For i As Integer = 0 To lbResults.Items.Count - 1

            Dim myListBoxItem As ListBoxItem = DirectCast(lbResults.ItemContainerGenerator.ContainerFromIndex(i), ListBoxItem)
            Dim myContentPresenter As ContentPresenter = FindVisualChild(Of ContentPresenter)(myListBoxItem)
            Dim myDataTemplate As DataTemplate = myContentPresenter.ContentTemplate

            Dim rctSuccess As Rectangle = DirectCast(myDataTemplate.FindName("rctProgSuccess", myContentPresenter), Rectangle)


            rctSuccess.Width = 100
            rctSuccess.Fill = Brushes.Red

        Next

使用以下功能:

私有函数FindVisualChild(of ChildItem As DependencyObject)(obj As DependencyObject)as childItem

For i As Integer = 0 To VisualTreeHelper.GetChildrenCount(obj) - 1

    Dim child As DependencyObject = VisualTreeHelper.GetChild(obj, i)

    If child IsNot Nothing AndAlso TypeOf child Is childItem Then
        Return DirectCast(child, childItem)
    Else

        Dim childOfChild As childItem = FindVisualChild(Of childItem)(child)
        If childOfChild IsNot Nothing Then
            Return childOfChild
        End If

    End If

Next

Return Nothing

结束功能

但是声明的myListBoxItem总是填充为空。我相信我错过了一些基本的东西,但我真的很想听到我的耳朵,我很高兴听到任何反馈 - 即使有一种完全不同的方式来实现我正在做的事情......使用DataGrids或任何东西?

非常感谢!

1 个答案:

答案 0 :(得分:0)

如果我理解你的问题,这样的事情应该有效。首先:处理Rectangle上的Loaded事件:

<Rectangle Loaded="rctProgSuccess_Loaded" Name="rctProgSuccess" HorizontalAlignment="Left" Height="28" Stroke="{x:Null}" VerticalAlignment="Top" Width="280">
    ...
</Rectangle>

这将为每个矩形调用rctProgSuccess_Loaded方法,将矩形实例作为参数传递。在您的代码隐藏中,只需执行:

Private Sub rctProgSuccess_Loaded(sender As Object, e As RoutedEventArgs)
    Dim rctProgSuccess As Rectangle = DirectCast(sender, Rectangle)

    'Obviously edit the following part to match the type of data of the items that populate your ListBox
    Dim yourItem As YourClass = DirectCast(rctProgSuccess.DataContext, YourClass)
    rctProgSuccess.Width = yourItem.yourPercentage 'or whatever
End Sub