2013-10-01 3 views
0

Я хочу создать единую сетку в wpf.Настройте единую сетку на число детей

Когда у меня есть 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> 

Binding to Children.Count

я нашел в этом посте, что я должен был сделать пользовательский UniformGrid так что Children.count сетки на самом деле работает, так что я сделал это.

Этот код работает, но у меня остается одна проблема.

Эти кнопки могут быть динамически сделаны видимыми или свернутыми, а когда кнопка рушится, я не хочу, чтобы они имели значение для количества строк. Когда кнопка 3 & 4 рушится, я не хочу иметь 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 ... вместо этого вы можете реализовать это как DependencyProperty.

+0

ВидимыйКонстант всегда возвращает 0, даже если я заменю ваш linq только на Children.Count(). Любая идея, почему это так? –

+0

У меня уже есть событие PropertyChanged в методах добавления/удаления ObservableUIElementCollection. Здесь вы можете найти класс ObseravbleUIElementCollection: http://stackoverflow.com/questions/3520060/binding-to-children-count –

+0

'Children.Count()' все еще 'LinQ' ...' Children.Count' не является ,В любом случае, я думаю, это потому, что коллекция элементов не реализует интерфейс 'INotifyPropertyChanged'. Я знаю, что вы сказали, что реализовали это, но я всегда добавляю «ручной» вызов «NotifyPropertyChanged» («VisibleCount»); сразу после любого кода, который добавляет или удаляет элементы из коллекции ... он работает нормально для меня. – Sheridan

1

Один из способов сделать это - добавить/удалить слушателя в IsVisibleChanged в UIElement в методах добавления и удаления вашей униформы.

И поместите логику в обработчик для вычисления строк/столбцов, зависящих от видимых детей. то вам не потребуется привязка к строкам/столбцам и конвертеру.

ie. в методе Add

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 
    } 

можно скорее создать отдельный метод, чтобы сделать это, и называют этот метод из Добавьте элемент и удалить элемент метода также. Не забывайте удалять обработчик при удалении элемента в методе удаления Метод

Смежные вопросы