0

我有以下附加属性:-

public partial class GridViewProperties
{

    public static readonly DependencyProperty DoAutoSizeColumnsProperty =
                DependencyProperty.RegisterAttached("DoAutoSizeColumns", 
                typeof(bool), 
                typeof(GridViewProperties),
                new FrameworkPropertyMetadata(false, 
                                                FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | 
                                                FrameworkPropertyMetadataOptions.AffectsMeasure |
                                                FrameworkPropertyMetadataOptions.AffectsArrange |
                                                FrameworkPropertyMetadataOptions.AffectsParentArrange |
                                                FrameworkPropertyMetadataOptions.AffectsParentMeasure |
                                                FrameworkPropertyMetadataOptions.AffectsRender,
                                                DoAutoSizeColumnsChanged));

    public static bool GetDoAutoSizeColumns(DependencyObject obj)
    {
        return (bool)obj.GetValue(DoAutoSizeColumnsProperty);
    }

    public static void SetDoAutoSizeColumns(DependencyObject obj, bool value)
    {
        obj.SetValue(DoAutoSizeColumnsProperty, value);
    }

    private static void DoAutoSizeColumnsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var gv = obj as GridView;

        if (gv == null)
            return;

        if (e.NewValue != null && (bool)e.NewValue)
        {
            AutoSizeColumns(gv.Columns);
            SetDoAutoSizeColumns(gv, false);
            gv.InvalidateProperty(GridView.ColumnCollectionProperty);
        }
    }
    private static void AutoSizeColumns(GridViewColumnCollection gvcc)
    {

        // same code as double clicking column gripper
        foreach (var gvc in gvcc)
        {
            // if already set to auto, toggle it so that we can re-run width="auto"
            //if (double.IsNaN(gvc.Width))
            gvc.Width = gvc.ActualWidth;
            // now do it                
            gvc.Width = double.NaN;
            //gvc.InvalidateProperty(GridViewColumn.WidthProperty);
            //gvc.ClearValue(GridViewColumn.WidthProperty);
        }
    } 
}

我以下列方式在 XAML 中使用它:

<Style x:Key="AutoColumnStyle" TargetType="ListView">
        <Setter Property="View">
            <Setter.Value>
                 <GridView infra:GridViewProperties.AutoSizeColumns="{Binding Path=DataContext.DoAutoSizeColumns, Source={x:Reference uc}}">
                    <GridViewColumn  Width="auto"   Header="Title"  CellTemplate="{StaticResource Name}" />
                     <GridViewColumn Width="auto"   Header="First" CellTemplate="{StaticResource First}"/>                         
                     <GridViewColumn Width="auto"   Header="Last" CellTemplate="{StaticResource Last}"/>                         
                 </GridView>
             </Setter.Value>
        </Setter>

上面是在 UserControl.Resources 中。

XAML 的其余部分是:

<ListView ItemsSource="{Binding Names}" VerticalAlignment="Top" HorizontalAlignment="Left"
              ScrollViewer.VerticalScrollBarVisibility="Auto" 
              ScrollViewer.HorizontalScrollBarVisibility="Auto" 
              SelectionMode="Single"
              x:Name="ListViewContracts"
              KeyboardNavigation.TabNavigation="Continue"
              KeyboardNavigation.DirectionalNavigation="Cycle" 
              Style="{StaticResource AutoColumnStyle}" 
          >
    <ListView.ItemContainerStyle >
        <Style BasedOn="{StaticResource ListViewItemContainerStyle}" TargetType="ListViewItem">                
            <Setter Property="Focusable" Value="False" />
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        </Style>                
    </ListView.ItemContainerStyle>
</ListView>

(我也尝试过没有 Width="auto" )。

每当我在 ViewModel 中设置 DoAutoSizeColumns = true 时,我看到附加属性中的所有内容都按预期工作,除了它的设计目的是 gridview 列没有根据该列中的最大项目调整大小(即使我看到 gv.Width 切换from 和 to double.Nan 这就是调整大小的工作方式)。

如您所见,我在附加属性中尝试了许多变体,其中大部分都被注释掉了,包括添加所有 FrameworkPoprertyMetadataOptions 并尝试各种 InvalidatePoperty 尝试,以及 UIPropertyMetadata (以及 DynamicResource )。

我错过了什么?

更新

这个附加属性在其他 GridViews 中工作,我在这里看到的唯一区别是 - 我需要在 ListView 中切换 GridViews,这没有在上面指出 - 但关键区​​别是我作为样式而不是直接注入。(再想一想,情况可能并非如此,因为这些其他 GridView 的列中的第一个项目始终是最大的项目)。

4

1 回答 1

0

这与注入一种风格有关。

我有两个不同的 GridView 由布尔值切换,并使用 DataTrigger 注入备用的,AutoSizeColumns 在那个备用的 GridView 上运行良好!所以我让这两种样式都由 DataTrigger 注入,而不是像上面的 XAML 中那样由一个 setter 设置默认值。

至于为什么会出现这种情况,我有兴趣找出答案。至少我有一种完全 MVVM 方式来自动调整列大小,这是我在其他 SO 答案中没有看到的。

(顺便说一句,我还有其他附加属性不需要我手动触发自动调整大小,我只是写了这个版本来识别问题)。

于 2012-07-18T09:30:36.270 回答