带有DataTemplate的UniformGrid触发器无法按预期工作,WPF

时间:2017-06-13 14:19:04

标签: wpf itemscontrol stackpanel uniformgrid

我在UserControl中托管了64 ItemsControl的列表,DataContext是一个对象数组。然后DataContext的单个实例的UserControl成为对象的实例。

对象有一个名为Exists的布尔变量,这是一个DataTemplate触发器,用于确定是否显示Usercontrol

我使用Uniformgrid来显示列表,但我遇到了一些奇怪的行为。 Usercontrol不会调整大小。见附图。如果我改用StackPanel,它就可以了。但我想改用UnifromGrid

以下是代码 - 只有4个对象将Exist变量设置为true。

    <Grid Grid.Row="1" Grid.Column="1" x:Name="gridSome" Background="#FF5AC1F1">
        <Viewbox>
            <ItemsControl ItemsSource="{Binding SomeVM.SomeModel.SomeArray}"  
                          Margin="15" HorizontalAlignment="Center" VerticalContentAlignment="Center">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <tensioner:UCView  Margin="5"/>
                        <DataTemplate.Triggers>
                            <DataTrigger Binding="{Binding Exists}" Value="False">
                                <Setter Property="Visibility" Value="Collapsed"/>
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <!--<StackPanel IsItemsHost="true"/> This works-->
                        <UniformGrid Columns="1"/> <!-- This does not work-->
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
             </ItemsControl>
        </Viewbox>
    </Grid>

Uniform Grid

Stack Panel

----- ------更新

// SSCCE 主窗口

<Window x:Class="WpfAppItemIssue.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfAppItemIssue"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainViewModel/>
    </Window.DataContext>
    <Grid>
        <!--<Viewbox>-->
            <ItemsControl ItemsSource="{Binding Model.Cars}">
            <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBox Text="ABC"></TextBox>
                        <DataTemplate.Triggers>
                            <DataTrigger Binding="{Binding exists}" Value="False">
                                <Setter Property="Visibility" Value="Collapsed"/>
                            </DataTrigger>
                        </DataTemplate.Triggers>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <UniformGrid Columns="1"/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        <!--</Viewbox>-->
    </Grid>
</Window>

MainViewModel

using System.ComponentModel;

namespace WpfAppItemIssue
{
    class MainViewModel:INotifyPropertyChanged
    {

        public MainViewModel()
        {
            Model = new MainModel();
        }

        private MainModel model;
        public MainModel Model
        {
            get
            {
                return model;
            }
            set
            {
                model = value;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }
}

模型

namespace WpfAppItemIssue
{
    class MainModel
    {
        public Car[] Cars { get; set; }

        public MainModel()
        {
            Cars = new Car[64];
            for (int i = 0; i < Cars.Length; i++)
            {
                Cars[i] = new Car(i);
            }
        }
    }

    internal class Car
    {
        public int someVal { get; set; }
        public bool exists { get; set; }

        public Car(int someVal)
        {
            this.someVal = someVal;
            if (someVal < 5)  //Just enable few items for debug
            {
                exists = true;
            }
            else
            {
                exists = false;
            }
        }
    }
}

见附图:

图1显示了设计视图。为什么用户控件没有调整大小? 图2显示了On Execute。为什么用户控件没有调整大小? 图3显示了On Any resize事件。控件正在正确调整大小。 Design View Execute Resize

2 个答案:

答案 0 :(得分:1)

这不是一种奇怪的行为,但它是UniformGrid的工作方式。 作为ItemsPanel的{​​{1}},ItemsControl使用UniformGrid集合来确定行数和列数。将放置在ItemSource中的项目是否可见无关紧要 - 所有网格单元格的宽度和高度都相同。因此,UniformGridDataTrigger的布局没有影响,只会影响项目的可见性。

UniformGrid以不同的方式运作。没有单元格,StackPanel排列所有可见项目,使其占用可用空间。

答案 1 :(得分:1)

我在评论中讨论后终于得到了你的问题。您DataTrigger中的ItemTemplate全部都是ItemContainerStyle。只需将其移至Triggers <ItemsControl ItemsSource="{Binding Model.Cars}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <UniformGrid Columns="1"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemContainerStyle> <Style TargetType="{x:Type ContentPresenter}"> <Style.Triggers> <DataTrigger Binding="{Binding exists}" Value="False"> <Setter Property="Visibility" Value="Collapsed"/> </DataTrigger> </Style.Triggers> </Style> </ItemsControl.ItemContainerStyle> <ItemsControl.ItemTemplate> <DataTemplate> <TextBox Text="ABC"></TextBox> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> ,即可正确调整元素大小。

TextBox

请注意,ItemsControl'es将仅按“边框”调整大小(此行为显示在您的上一张图片上),字体大小不会更改。如果您想要使用其内容统一扩展元素,则需要将Viewbox包裹到// swift-tools-version:3.1 import PackageDescription let package = Package( name: "MyPackage", dependencies: [ .Package(url: "https://github.com/WeirdMath/Scrape.git", majorVersion: 1) ] )