我想在 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>
绑定到子项.计数
我在这篇文章中发现我必须制作一个自定义的 UniformGrid,以便网格的 Children.count 真正工作,所以我这样做了。
这段代码都可以工作,但我还有一个问题。
这些按钮可以动态地可见或折叠,当按钮折叠时,我不希望它们对行数产生影响。当按钮 3 和 4 折叠时,我不想有第二行。
知道如何实现这一目标吗?
在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>
唯一需要注意的一点是,每当在Grid.Children
集合中添加或删除项时,都可能需要调用 INotifyPropertyChanged.PropertyChanged
事件...或者,您可以改为将其实现为DependencyProperty
。
一种方法是在统一网格的添加/删除方法的UIElement上将侦听器添加/删除到IsVisibleChanged。
并将逻辑放在处理程序中,以计算在可见子项上丢弃的行/列。 那么,您将不需要行/列和转换器的自绑定。
即在添加方法中
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
}
您可以创建单独的方法来执行此操作,并从添加元素和删除元素方法调用该方法。在删除方法中的元素时不要忘记删除处理程序