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

UniformGrid with DataTemplate trigger not working as expected, WPF

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

对象有一个名为 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>

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

//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>

主视图模型

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 事件。控件正在正确调整大小。

这不是什么奇怪的行为,而是 UniformGrid 的工作方式。 作为 ItemsControlItemsPanelUniformGrid 使用 ItemSource 集合来确定行数和列数。将放置在 UniformGrid 中的项目是否可见并不重要 - 所有网格单元格都具有相同的宽度和高度。所以你的 DataTriggerUniformGrid 的布局没有影响,它只影响项目的可见性。

StackPanel 的工作方式不同。没有单元格,StackPanel 排列所有 visible 项目,使它们占据可用的 space.

好吧,在评论中讨论后,我终于解决了你的问题。在你的 ItemTemplate 中都是关于 DataTrigger 的。只需将其移动到 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 只会调整 "by border" 的大小(此行为显示在您的最后一张图片上),字体大小不会更改。如果你想用它们的内容统一缩放你的元素,你真的需要将 ItemsControl 包装到 Viewbox.