也有類似的問題到此here和here,但我已經嘗試了它們兩個中的所有內容,但它們不能解決我的問題。如何使包含ItemsControl的WPF網格具有相同大小的列
我想在WPF(佈局)網格的屏幕上顯示一個checkBox網格。這些複選框具有可變長度文本。我希望所有的列都是相同的寬度,並且它們全部顯示沒有截斷的文本。也就是說,我需要它們都具有最長文本的寬度。我希望屏幕本身能夠容納內容。也就是說,只需顯示所有複選框即可。
複選框的列表是可變的,這取決於其他因素,所以我使用ItemsControl來顯示它們。代碼的簡化版本如下。
如果您運行此操作,那麼第二列中的「長文本」列將比具有較短文本的列寬很多。爲了使它們具有相同的寬度,我嘗試使用SharedSizeGroup,並嘗試在列加載事件中設置MaxWidth = ActualWidth,這些解決方案在其他地方提出,但這些都不起作用。
我確定必須有一個簡單的答案,這似乎是一個相當基本的事情想要做一個佈局控制。請問我做錯了什麼?
XAML:
<Window x:Class="GridColsEqualSize.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" SizeToContent="WidthAndHeight" FontSize="25">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" /> <!-- In the real project second row is for OK/Cancel buttons -->
</Grid.RowDefinitions>
<ItemsControl ItemsSource="{Binding CheckBoxItems}" Grid.Row="0" Grid.Column="0">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<!--Whatever I do I can't get the screen to resize and the cols to have the same width-->
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
<ColumnDefinition Width="Auto" SharedSizeGroup="A" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Text}" IsChecked="{Binding Enabled}"
Margin="0,0,10,0"></CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemContainerStyle>
<Style>
<Style.Setters>
<Setter Property="Grid.Row" Value="{Binding GridRow}" />
<Setter Property="Grid.Column" Value="{Binding GridColumn}" />
</Style.Setters>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</Grid>
</Window>
C#:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
CheckBoxItems = new List<CheckBoxItem>
{
new CheckBoxItem("A", true),
new CheckBoxItem("B"),
new CheckBoxItem("C", true),
new CheckBoxItem("D"),
new CheckBoxItem("E", true),
new CheckBoxItem("F"),
new CheckBoxItem("G"),
new CheckBoxItem("Long text", true),
new CheckBoxItem("")
};
SetCheckBoxItemRowsAndColumns();
}
public List<CheckBoxItem> CheckBoxItems { get; set; }
private void SetCheckBoxItemRowsAndColumns()
{
int currentColumn = 0;
int currentRow = 0;
foreach (CheckBoxItem checkBoxItem in CheckBoxItems)
{
checkBoxItem.GridColumn = currentColumn;
checkBoxItem.GridRow = currentRow;
if (currentColumn != 2)
{
currentColumn++;
}
else
{
currentRow++;
currentColumn = 0;
}
}
}
public class CheckBoxItem
{
public CheckBoxItem(string text, bool enabled = false)
{
Text = text;
Enabled = enabled;
}
public string Text { get; set; }
public bool Enabled { get; set; }
public int GridRow { get; set; }
public int GridColumn { get; set; }
}
private void FrameworkContentElement_OnLoaded(object sender, RoutedEventArgs e)
{
((ColumnDefinition)sender).MaxWidth = ((ColumnDefinition)sender).ActualWidth;
}
}
您是否嘗試使用UniformGrid? UniformGrid安排一個Grid,其中所有的單元格和行都具有相同的大小。 – gomi42 2015-03-03 10:18:20
使用UniformGrid可以節省'GridRow'和'GridColumn'視圖模型的屬性,並且會使'ItemContainerStyle'變得冗餘。 ItemsPanelTemplate僅僅是''。也不需要你的'SetCheckBoxItemRowsAndColumns'方法。少得多的XAML和代碼。所以我不同意SharedSizeScope是「正確的解決方案」。 –
Clemens
2015-03-03 11:32:15
在實際代碼中(與此處的簡化示例相反),複選框分組。每個組出現在一行中,或者如果複選框比網格中的列多,則會將其包裝到下一行。所以第一行可以有兩個複選框,下一個六個等等。這是上面代碼的一個相當簡單的擴展,但我認爲你不能用UniformGrid來完成。 – 2015-03-04 18:16:42