Silverlight - Сетка со списком ListBox и списком, содержащим выравнивание StackPanel - PullRequest
1 голос
/ 28 мая 2011

У меня есть таблица с 2 строками и 4 столбцами.

Первая строка содержит заголовки. Вторая строка содержит содержимое ListBox, горизонтально растянутое, с ListBoxItems, являющимся StackPanels с горизонтальной ориентацией с 4 элементами столбца (4 textBlocks), я хочу, чтобыбыть в состоянии иметь столбцы, имеющие одинаковую ширину столбцов сетки

Как мне это сделать?Большое спасибо за вашу помощь !!!

Это то, что у меня есть сейчас,

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    xmlns:local="clr-namespace:SilverlightForum"
    mc:Ignorable="d"
    x:Class="SilverlightForum.Assets.ForumBoardControl">

    <UserControl.Resources>
        <Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
        </Style>
    </UserControl.Resources>

    <StackPanel Orientation="Vertical" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Stretch">
        <sdk:DataPager DisplayMode="FirstLastPreviousNext" Source="{Binding}" x:Name="dataPagerListBoxBoardTop" HorizontalAlignment="Right"/>
        <Grid Margin="0" HorizontalAlignment="Stretch">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="70"/>
                <ColumnDefinition Width="350*"/>
                <ColumnDefinition Width="70*"/>
                <ColumnDefinition Width="70*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Border x:Name="StackPanelBoardColumn1" CornerRadius="6,0,0,0" Padding="0" Margin="0" Height="28" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" BorderThickness="0">
                <Border.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Red" Offset="0"/>
                        <GradientStop Color="#FFA6BACE" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>
            </Border>
            <Border x:Name="StackPanelBoardColumn2" CornerRadius="0" Padding="0" Margin="0" Height="28" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" BorderThickness="0">
                <Border.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Blue" Offset="0"/>
                        <GradientStop Color="#FFA6BACE" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>
            </Border>
            <Border x:Name="StackPanelBoardColumn3" CornerRadius="0" Padding="0" Margin="0" Height="28" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="2" VerticalAlignment="Top" BorderThickness="0">
                <Border.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Green" Offset="0"/>
                        <GradientStop Color="#FFA6BACE" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>
            </Border>
            <Border x:Name="StackPanelBoardColumn4" CornerRadius="0,6,0,0" Padding="0" Margin="0" Height="28" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="3" VerticalAlignment="Top" BorderThickness="0">
                <Border.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF6D869F" Offset="0"/>
                        <GradientStop Color="#FFA6BACE" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>
            </Border>
            <ListBox x:Name="listBoxBoard" Grid.ColumnSpan="4" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Transparent" BorderThickness="0" Margin="0" Padding="0" HorizontalContentAlignment="Stretch" ItemContainerStyle="{StaticResource ListBoxItemStyle}" ItemsSource="{Binding}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <Grid Margin="0" HorizontalAlignment="Stretch" x:Name="GridBoard">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="70"/>
                                <ColumnDefinition Width="350*"/>
                                <ColumnDefinition Width="70*"/>
                                <ColumnDefinition Width="70*"/>
                            </Grid.ColumnDefinitions>
                            <StackPanel Grid.Column="0" Margin="0,0,1,0" Background="#FFE7EAEF" Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                                <HyperlinkButton FontSize="16" Margin="0,0,0,0" Padding="8" Foreground="Black" FontWeight="Bold"/>
                            </StackPanel>
                            <StackPanel Grid.Column="1" Margin="1,0,1,0" Background="#FFF0F4F7" Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                                <HyperlinkButton FontSize="14" Margin="0" Padding="8,8,8,0" Foreground="#FFD97B33" FontWeight="Bold" Content="{Binding TopicName}" />
                                <sdk:Label Margin="0" Padding="8,0,8,8" Foreground="Black" Content="{Binding UserName, StringFormat='Started by {0}'}" />
                            </StackPanel>
                            <StackPanel Grid.Column="2" Margin="1,0,1,0" Background="#FFE7EAEF" Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                                <TextBlock Margin="0" Padding="8,8,8,0" d:IsHidden="True" ><Run FontWeight="Bold" Text="{Binding TopicPostsCount}" /><Run Text=" Replies(s)" Foreground="#FF000000" /></TextBlock>
                                <TextBlock Margin="1,0,0,1" Padding="8,0,8,8"><Run FontWeight="Bold" Text="{Binding TopicViewsCount}" /><Run Text=" Views(s)" Foreground="#FF000000" /></TextBlock>
                            </StackPanel>
                            <StackPanel Grid.Column="3" Margin="1,0,0,0" Background="#FFF0F4F7" Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                                <sdk:Label Margin="0" Padding="4,4,4,0" Content="Last post on {Date}"/>
                                <sdk:Label Margin="0" Padding="4,0,4,4" Content="by {User}"/>
                            </StackPanel>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
        <sdk:DataPager DisplayMode="FirstLastPreviousNext" Source="{Binding}" x:Name="dataPagerListBoxBoardBottom" HorizontalAlignment="Right"/>
    </StackPanel>
</UserControl>

1 Ответ

1 голос
/ 28 мая 2011

Полагаю, вы можете привязать ширину ваших текстовых блоков к фактической ширине какой-то "невидимой" сетки, которую вы растянули в одном столбце.

Примерно так (непроверенный код ...):

<Grid>
  <Grid.ColumnDefinitions>
     <ColumnDefinition Width="*"/>
     <ColumnDefinition Width="*"/>
     <ColumnDefinition Width="*"/>
     <ColumnDefinition Width="*"/>
  </Grid.ColumnDefinitions>
  <Grid x:Name="invisibleGrid" />
</Grid>

Затем вы привязываете ширину текстовых полей к ActualWidth invisibleGrid.

<TextBlock x:Name="textBlockColumn1" Width="{Binding ActualWidth, ElementName=invisibleGrid}"/>

Поскольку существуют известные проблемы, по которым ActualWidth не обновляется, посмотрите здесь: Привязка к ActualWidth не работает

Это обходной путь для этой проблемы.

Hopeэто помогает.

BR,

TJ

PS Опубликовать немного XAMl, так что, возможно, я могу помочь немного больше.

EDIT : См. Мой комментарий ...

Добавьте этот класс в свое решение ( Привязка к ActualWidth не работает ):

public class ActualSizePropertyProxy : FrameworkElement, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public FrameworkElement Element
        {
            get { return (FrameworkElement)GetValue(ElementProperty); }
            set { SetValue(ElementProperty, value); }
        }

        public double ActualHeightValue
        {
            get { return Element == null ? 0 : Element.ActualHeight; }
        }

        public double ActualWidthValue
        {
            get { return Element == null ? 0 : Element.ActualWidth; }
        }

        public static readonly DependencyProperty ElementProperty =
            DependencyProperty.Register("Element", typeof(FrameworkElement), typeof(ActualSizePropertyProxy),
                                        new PropertyMetadata(null, OnElementPropertyChanged));

        private static void OnElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ActualSizePropertyProxy)d).OnElementChanged(e);
        }

        private void OnElementChanged(DependencyPropertyChangedEventArgs e)
        {
            FrameworkElement oldElement = (FrameworkElement)e.OldValue;
            FrameworkElement newElement = (FrameworkElement)e.NewValue;

            newElement.SizeChanged += new SizeChangedEventHandler(Element_SizeChanged);
            if (oldElement != null)
            {
                oldElement.SizeChanged -= new SizeChangedEventHandler(Element_SizeChanged);
            }
            NotifyPropChange();
        }

        private void Element_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            NotifyPropChange();
        }

        private void NotifyPropChange()
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("ActualWidthValue"));
                PropertyChanged(this, new PropertyChangedEventArgs("ActualHeightValue"));
            }
        }
    }

Вот мой xaml:

<StackPanel Orientation="Vertical" Margin="0" VerticalAlignment="Top" HorizontalAlignment="Stretch">
        <Controls:DataPager DisplayMode="FirstLastPreviousNext" Source="{Binding}" x:Name="dataPagerListBoxBoardTop" HorizontalAlignment="Right"/>
        <Grid Margin="0" HorizontalAlignment="Stretch">
            <Grid.Resources>
                <c:ActualSizePropertyProxy Element="{Binding ElementName=invisibleColumnGrid1}" x:Name="column1" />
                <c:ActualSizePropertyProxy Element="{Binding ElementName=invisibleColumnGrid2}" x:Name="column2" />
                <c:ActualSizePropertyProxy Element="{Binding ElementName=invisibleColumnGrid3}" x:Name="column3" />
                <c:ActualSizePropertyProxy Element="{Binding ElementName=invisibleColumnGrid4}" x:Name="column4" />
            </Grid.Resources>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="70"/>
                <ColumnDefinition Width="350*"/>
                <ColumnDefinition Width="70*"/>
                <ColumnDefinition Width="70*"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid x:Name="invisibleColumnGrid1"/>
            <Grid Grid.Column="1" x:Name="invisibleColumnGrid2"/>
            <Grid Grid.Column="2" x:Name="invisibleColumnGrid3"/>
            <Grid Grid.Column="3" x:Name="invisibleColumnGrid4"/>
            <Border x:Name="StackPanelBoardColumn1" CornerRadius="6,0,0,0" Padding="0" Margin="0" Height="28" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" BorderThickness="0">
                <Border.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Red" Offset="0"/>
                        <GradientStop Color="#FFA6BACE" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>
            </Border>
            <Border x:Name="StackPanelBoardColumn2" CornerRadius="0" Padding="0" Margin="0" Height="28" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" BorderThickness="0">
                <Border.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Blue" Offset="0"/>
                        <GradientStop Color="#FFA6BACE" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>
            </Border>
            <Border x:Name="StackPanelBoardColumn3" CornerRadius="0" Padding="0" Margin="0" Height="28" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="2" VerticalAlignment="Top" BorderThickness="0">
                <Border.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="Green" Offset="0"/>
                        <GradientStop Color="#FFA6BACE" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>
            </Border>
            <Border x:Name="StackPanelBoardColumn4" CornerRadius="0,6,0,0" Padding="0" Margin="0" Height="28" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="3" VerticalAlignment="Top" BorderThickness="0">
                <Border.Background>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FF6D869F" Offset="0"/>
                        <GradientStop Color="#FFA6BACE" Offset="1"/>
                    </LinearGradientBrush>
                </Border.Background>
            </Border>
            <ListBox 
                ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                ItemsSource="{Binding}"
                x:Name="listBoxBoard" Grid.ColumnSpan="4" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Transparent" BorderThickness="0" Margin="0" Padding="0" HorizontalContentAlignment="Stretch" ItemContainerStyle="{StaticResource ListBoxItemStyle}" >
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <StackPanel  Width="{Binding ElementName=column1, Path=ActualWidthValue}" Background="#FFE7EAEF" Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                                <HyperlinkButton FontSize="16" Margin="0,0,0,0" Padding="8" Foreground="Black" FontWeight="Bold"/>
                            </StackPanel>
                            <StackPanel Width="{Binding ElementName=column2, Path=ActualWidthValue}" Background="#FFF0F4F7" Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                                <HyperlinkButton FontSize="14" Margin="0" Padding="8,8,8,0" Foreground="#FFD97B33" FontWeight="Bold" Content="{Binding TopicName}" />
                                <sdk:Label Margin="0" Padding="8,0,8,8" Foreground="Black" Content="{Binding UserName, StringFormat='Started by {0}'}" />
                            </StackPanel>
                            <StackPanel Width="{Binding ElementName=column3, Path=ActualWidthValue}" Background="#FFE7EAEF" Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                                <TextBlock Margin="0" Padding="8,8,8,0" d:IsHidden="True" ><Run FontWeight="Bold" Text="{Binding TopicPostsCount}" /><Run Text=" Replies(s)" Foreground="#FF000000" /></TextBlock>
                                <TextBlock Margin="1,0,0,1" Padding="8,0,8,8"><Run FontWeight="Bold" Text="{Binding TopicViewsCount}" /><Run Text=" Views(s)" Foreground="#FF000000" /></TextBlock>
                            </StackPanel>
                            <StackPanel Width="{Binding ElementName=column4, Path=ActualWidthValue}" Background="#FFF0F4F7" Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                                <sdk:Label Margin="0" Padding="4,4,4,0" Content="Last post on {Date}"/>
                                <sdk:Label Margin="0" Padding="4,0,4,4" Content="by {User}"/>
                            </StackPanel>
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
        <Controls:DataPager DisplayMode="FirstLastPreviousNext" Source="{Binding}" x:Name="dataPagerListBoxBoardBottom" HorizontalAlignment="Right"/>
    </StackPanel>

Я создаю невидимую сетку для каждой строки.Затем использовали их для наблюдения ширины ActualSizePropertyProxy и использовали эти прокси для привязки ширины стековых панелей.

...