2017-06-13 49 views
0

我在ItemsControl中托管了64个UserControl的列表,DataContext是一个对象数组。然后,UserControl的单个实例的DataContext将成为对象的实例。带DataTemplate触发器的UniformGrid无法按预期工作,WPF

对象有一个名为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显示执行。为什么用户控件不能调整大小? 图3显示了任何调整大小事件。控件正在正确调整大小。 Design ViewExecute Resize

+0

如果'StackPanel'对你更好,你为什么需要'UniformGrid'? – dymanoid

+0

XAML中“Viewbox”的用途是什么? – Maxim

+0

我想缩放'ItemsControl'以适应'Grid'。而且,现在我想缩放'UserControls'以适应多列中的'UniformGrid'。 –

回答

1

嗯,我终于在讨论后的评论中得到了你的问题。这是关于ItemTemplate中的DataTrigger。只需将其移动到ItemContainerStyleTriggers并且元素将被正确调整大小。

<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“ES将只调整‘的边界’(这种行为显示在你的最后一张照片),字体大小不会改变。如果你想用他们的内容来统一你的元素,你真的需要将ItemsControl换成Viewbox

+0

这就是@Maxim!我已经投票并接受你的答案作为解决方案。谢谢。 –

1

这不是一个怪异的行为,但它的UniformGrid的工作方式。作为ItemsControlItemsPanelUniformGrid使用ItemSource集合来确定行数和列数。放置在UniformGrid中的项目是否可见 - 无关紧要 - 所有网格单元具有相同的宽度和高度。因此,您的DataTriggerUniformGrid的布局没有影响,它只影响项目的可见性。

StackPanel以不同的方式工作。没有单元格,StackPanel将所有的项目排列成可用空间。

+0

好吧,它很奇怪,因为在设计时 - 这些项目占用了可用空间。当我编译和执行时,他们没有。我不能使用'StackPanel',因为有64个用户控件,我希望它们被排列成多行,'UniformGrid'可以做。 –