2015-03-03 89 views
1

也有類似的問題到此herehere,但我已經嘗試了它們兩個中的所有內容,但它們不能解決我的問題。如何使包含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; 
     } 
    } 
+1

您是否嘗試使用UniformGrid? UniformGrid安排一個Grid,其中所有的單元格和行都具有相同的大小。 – gomi42 2015-03-03 10:18:20

+0

使用UniformGrid可以節省'GridRow'和'GridColumn'視圖模型的屬性,並且會使'ItemContainerStyle'變得冗餘。 ItemsPanelTemplate僅僅是''。也不需要你的'SetCheckBoxItemRowsAndColumns'方法。少得多的XAML和代碼。所以我不同意SharedSizeScope是「正確的解決方案」。 – Clemens 2015-03-03 11:32:15

+0

在實際代碼中(與此處的簡化示例相反),複選框分組。每個組出現在一行中,或者如果複選框比網格中的列多,則會將其包裝到下一行。所以第一行可以有兩個複選框,下一個六個等等。這是上面代碼的一個相當簡單的擴展,但我認爲你不能用UniformGrid來完成。 – 2015-03-04 18:16:42

回答

1

一切都OK了:)你已經選擇了正確的解決方案 'SharedSizeGroup'

你只需添加Grid.IsSharedSizeScope =對您的ItemsControl「True」:

... 
    </Grid.RowDefinitions> 
    <ItemsControl Grid.IsSharedSizeScope="True" ItemsSource="{Binding CheckBoxItems}" Grid.Row="0" Grid.Column="0" > 
     <ItemsControl.ItemsPanel> 
    ... 
+0

完美,謝謝 – 2015-03-03 10:49:55

相關問題