如何防止ListView切断项目

时间:2011-03-12 16:27:13

标签: wpf listview mvvm-light

我正在使用扩展自定义属性ListViewcolumns.Stretch的ListView框。这样我就可以有3列无论窗口大小如何均匀分布。我的问题是在listview项目结束时被“切断”

所以我的列表视图包含3列,红色,绿色和黑色,当我插入一个项目时,它插入到相应的列中,另外两列插入空白文本。它将项目插入0位置,因此它始终显示在顶部并向下推动其他所有内容。默认情况下,滚动条关闭。

- 目标是让3个列占据整个窗口空间,无论窗口有多大或多小,并适当调整文本大小(最大高度约为100-150)。然后当行填满整个集合时,底行不能“跨越”视图,它应该全部在视图中或视图中没有。

无论如何 - 代码。任何帮助将不胜感激,我可以硬编码视图框的最大高度,直到我找到适合我的目标显示器的完美尺寸,但理想情况下我希望它适当调整大小

的ListView

<ListView Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Transparent" Margin="15,10,5,5"
                      FontFamily="Impact" FontWeight="Bold" BorderThickness="0" VerticalContentAlignment="Stretch"
                  ScrollViewer.VerticalScrollBarVisibility="{Binding VerticleScrollVisibility}" ScrollViewer.HorizontalScrollBarVisibility="Auto"
                  ItemsSource="{Binding PlayNumbers}"
                  ItemContainerStyle="{StaticResource ListViewStyle}" ext:ListViewColumns.Stretch="True">
                <ListView.View>
                    <GridView>
                        <GridView.ColumnHeaderContainerStyle>
                            <Style>
                                <Setter Property="FrameworkElement.Visibility" Value="Collapsed" />
                            </Style>
                        </GridView.ColumnHeaderContainerStyle>
                        <GridView.Columns>
                        <GridViewColumn Header="Red" CellTemplate="{StaticResource RedItemTemplate}" />
                            <GridViewColumn Header="Green" CellTemplate="{StaticResource GreenItemTemplate}" />
                            <GridViewColumn Header="Black" CellTemplate="{StaticResource BlackItemTemplate}" />
                        </GridView.Columns>
                    </GridView>
                </ListView.View>
    </ListView>

皮肤文件

    <!--        Templates for Number ListBox            -->
<DataTemplate x:Key="RedItemTemplate">
    <Viewbox MaxHeight="140" VerticalAlignment="Stretch">
        <TextBlock Text="{Binding Path=RedItem}" HorizontalAlignment="Center" Foreground="Red" />
    </Viewbox>
</DataTemplate>

<DataTemplate x:Key="GreenItemTemplate">
    <Viewbox MaxHeight="140" VerticalAlignment="Stretch">
        <TextBlock Text="{Binding Path=GreenItem}" HorizontalAlignment="Center" Foreground="Green" />
    </Viewbox>
</DataTemplate>

<DataTemplate x:Key="BlackItemTemplate">
    <Viewbox MaxHeight="140" VerticalAlignment="Stretch">
        <TextBlock Text="{Binding Path=BlackItem}" HorizontalAlignment="Center" Foreground="LightGray" />
    </Viewbox>
</DataTemplate>

<Style x:Key="ListViewStyle" TargetType="{x:Type ListViewItem}">
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="HorizontalContentAlignment" Value="Stretch" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ListViewItem}">
                <Border x:Name="Bd" Background="{TemplateBinding Background}"
                        SnapsToDevicePixels="True" BorderThickness="0,0,0,1" BorderBrush="Transparent">
                    <GridViewRowPresenter VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="false" />
                    <Trigger Property="IsMouseOver" Value="false" />
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

自定义属性

    /// <summary>
/// ListViewColumnStretch
/// </summary>
public class ListViewColumns : DependencyObject
{

    #region Fields

    /// <summary>
    /// Holds a reference to our parent ListView control
    /// </summary>
    private ListView _parentListView = null;

    #endregion

    #region Dependency Property Infrastructure

    /// <summary>
    /// IsStretched Dependency property which can be attached to gridview columns.
    /// </summary>
    public static readonly DependencyProperty StretchProperty =
        DependencyProperty.RegisterAttached("Stretch",
        typeof(bool),
        typeof(ListViewColumns),
        new UIPropertyMetadata(true, null, OnCoerceStretch));


    /// <summary>
    /// Gets the stretch.
    /// </summary>
    /// <param name="obj">The obj.</param>
    /// <returns></returns>
    public static bool GetStretch(DependencyObject obj)
    {
        return (bool)obj.GetValue(StretchProperty);
    }

    /// <summary>
    /// Sets the stretch.
    /// </summary>
    /// <param name="obj">The obj.</param>
    /// <param name="value">if set to <c>true</c> [value].</param>
    public static void SetStretch(DependencyObject obj, bool value)
    {
        obj.SetValue(StretchProperty, value);
    }

    /// <summary>
    /// Called when [coerce stretch].
    /// </summary>
    /// <remarks>If this callback seems unfamilar then please read
    /// the great blog post by Paul jackson found here. 
    /// http://compilewith.net/2007/08/wpf-dependency-properties.html</remarks>
    /// <param name="source">The source.</param>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static object OnCoerceStretch(DependencyObject source, object value)
    {
        ListView lv = (source as ListView);

        //Ensure we dont have an invalid dependency object of type ListView.
        if (lv == null)
            throw new ArgumentException("This property may only be used on ListViews");

        //Setup our event handlers for this list view.
        lv.Loaded += new RoutedEventHandler(lv_Loaded);
        lv.SizeChanged += new SizeChangedEventHandler(lv_SizeChanged);
        return value;
    }

    #endregion

    #region Event Handlers

    /// <summary>
    /// Handles the SizeChanged event of the lv control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Windows.SizeChangedEventArgs"/> instance containing the event data.</param>
    private static void lv_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        ListView lv = (sender as ListView);
        if (lv.IsLoaded)
        {
            //Set our initial widths.
            SetColumnWidths(lv);
        }
    }

    /// <summary>
    /// Handles the Loaded event of the lv control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
    private static void lv_Loaded(object sender, RoutedEventArgs e)
    {
        ListView lv = (sender as ListView);
        //Set our initial widths.
        SetColumnWidths(lv);
    }
    #endregion

    #region Private Members

    /// <summary>
    /// Sets the column widths.
    /// </summary>
    private static void SetColumnWidths(ListView listView)
    {
        //Pull the stretch columns fromt the tag property.
        List<GridViewColumn> columns = (listView.Tag as List<GridViewColumn>);
        double specifiedWidth = 0;
        GridView gridView = listView.View as GridView;
        if (gridView != null)
        {
            if (columns == null)
            {
                //Instance if its our first run.
                columns = new List<GridViewColumn>();
                // Get all columns with no width having been set.
                foreach (GridViewColumn column in gridView.Columns)
                {
                    if (!(column.Width >= 0))
                        columns.Add(column);
                    else specifiedWidth += column.ActualWidth;
                }
            }
            else
            {
                // Get all columns with no width having been set.
                foreach (GridViewColumn column in gridView.Columns)
                    if (!columns.Contains(column))
                        specifiedWidth += column.ActualWidth;
            }

            // Allocate remaining space equally.
            foreach (GridViewColumn column in columns)
            {
                double newWidth = (listView.ActualWidth - specifiedWidth) / columns.Count;
                if (newWidth >= 0) column.Width = newWidth - 10;
            }

            //Store the columns in the TAG property for later use. 
            listView.Tag = columns;
        }
    }


    #endregion

}

2 个答案:

答案 0 :(得分:2)

我知道这是一个老问题,但这是另一个解决方案。在ListViewItem的样式上,还将Horizo​​ntalAlignment设置为Stretch,With设置为Auto。

    <!--ListViewItem-->
    <Style TargetType="ListViewItem" x:Key="ListViewItemStyle">
        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="Width" Value="Auto" />
    </Style>

答案 1 :(得分:0)

这有点间接,但是当遇到一个控件的局限时,为什么不尝试不同的方法呢?而不是使用ListView的GridView,尝试使用DataGrid,它允许比例列增长。我只想从你的'XAML发布一个精简版,但你会得到点(宽度=“33 *”)

<DataGrid>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Red" Width="33*"/>
        <DataGridTextColumn Header="Green" Width="33*"/>
        <DataGridTextColumn Header="Black" Width="33*"/>
     </DataGrid.Columns>
</DataGrid>