0

我想在 wpf 中制作一个 uniformGrid。

当我有 1 个孩子时,我希望它填充网格,2 个孩子我想要 2 列,当我有 3 或 4 个孩子时,我想要 2 行和 2 列。

所以我做了一个转换器来检查网格中有多少孩子,并据此决定行数/列数:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows;
using System.Globalization;

namespace UserControlSolution.Converter
{
    [ValueConversion(typeof(int), typeof(int))]
    public class CountToDimensionConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int itemsCount = (int)value;
            int dimensionLength = 1;
            if (itemsCount > 0)
            {   
                if (string.Equals((string)parameter, "Rows", StringComparison.OrdinalIgnoreCase))
                {
                    switch(itemsCount)
                    {
                        case 1: 
                        case 2: dimensionLength = 1;
                            break;
                        case 3: 
                        case 4: dimensionLength = 2;
                            break;
                    }
                }

                if (string.Equals((string)parameter, "Columns", StringComparison.OrdinalIgnoreCase))
                {
                    switch(itemsCount)
                    {
                        case 1: dimensionLength = 1;
                            break;
                        case 2: 
                        case 3: 
                        case 4: dimensionLength = 2;
                            break;
                    }
                }
            }

            return dimensionLength;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}

这是我的 xaml:

<customGridView:MyUniformGrid x:Name="AlarmButtonGrid" Margin="0,10" Grid.Row="2" Width="{Binding ActualWidth, ElementName=AlarmPictureBox}"
        Rows="{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=Rows}" 
        Columns="{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=Columns}"> 

       <Button x:Name="Button1" Content="Sluit" Height="35" Style="{StaticResource CustomButtonStyle}" Margin="5" />
       <Button x:Name="Button2" Content="Verbergen" Height="35" Style="{StaticResource CustomButtonStyle}" Margin="5"/>
       <Button x:Name="Button3" Visibility="Collapsed" Content="Extra rij" Height="35" Style="{StaticResource CustomButtonStyle}" Margin="5"/>
       <Button x:Name="Button4" Visibility="Collapsed" Content="Extra rij" Height="35" Style="{StaticResource CustomButtonStyle}" Margin="5"/>
</customGridView:MyUniformGrid>

绑定到 Children.Count

我在这篇文章中发现我必须制作一个自定义的 UniformGrid 以便网格的 Children.count 真正起作用,所以我这样做了。

这段代码一切正常,但我还有一个问题。

这些按钮可以动态显示或折叠,当按钮折叠时,我不希望它们与行数无关。当按钮 3 和 4 折叠时,我不想有第二行。

知道如何实现这一目标吗?

4

2 回答 2

2

在您的MyUniformGrid课程中,只需添加一个新属性:

public int VisibleCount
{
    get { return Children.OfType<UIElement>().Count(c => c.Visibility == 
              Visibility.Visible); }
}

...并与之绑定:

<customGridView:MyUniformGrid x:Name="AlarmButtonGrid" Margin="0,10" Grid.Row="2" 
    Width="{Binding ActualWidth, ElementName=AlarmPictureBox}" Rows="{Binding 
    RelativeSource={RelativeSource Self}, Path=VisibleCount, Converter={
    StaticResource CountToDimensionConverter}, ConverterParameter=Rows}" Columns="{
    Binding RelativeSource={RelativeSource Self}, Path=VisibleCount, Converter={
    StaticResource CountToDimensionConverter}, ConverterParameter=Columns}">                    
    <Button x:Name="Button1" Content="Sluit" Height="35" Style="{StaticResource CustomButtonStyle}" Margin="5" />
    <Button x:Name="Button2" Content="Verbergen" Height="35" Style="{StaticResource CustomButtonStyle}" Margin="5"/>
    <Button x:Name="Button3" Visibility="Collapsed" Content="Extra rij" Height="35" Style="{StaticResource CustomButtonStyle}" Margin="5"/>
    <Button x:Name="Button4" Visibility="Collapsed" Content="Extra rij" Height="35" Style="{StaticResource CustomButtonStyle}" Margin="5"/>
</customGridView:MyUniformGrid>

INotifyPropertyChanged.PropertyChanged唯一需要注意的是,每当您从集合中添加或删除项目时,您可能需要调用该事件Grid.Children......或者,您可以将其实现为 a DependencyProperty

于 2013-10-01T10:09:25.323 回答
1

一种方法是在您的 uniformgrid 的 Add/Remove 方法中的 UIElement 上添加/删除 IsVisibleChanged 的​​侦听器。

并将逻辑放入处理程序中以计算依赖于可见子项的行/列。那么您将不需要行/列和转换器的自绑定。

IE。在添加方法中

   element.IsVisibleChanged += new DependencyPropertyChangedEventHandler(Child_IsVisibleChanged);

然后在处理程序中

    private void Child_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        int visibleChildrenCount = 0;
        for (int i = 0; i < grid.Children.Count; i++)
        {
            if (grid.Children[i].Visibility == Visibility.Visible)
            {
                visibleChildrenCount++;
            }
        }

        //Here you can set your Rows and Columns depending on visiblechildrenCount
    }

您可以创建单独的方法来执行此操作,并从 Add element 和 remove element 方法调用该方法。在 Remove 方法中删除元素时不要忘记删除处理程序

于 2013-10-01T10:33:23.080 回答