Есть ли способ ссылаться на столбец таблицы с помощью x: Name в качестве альтернативы его нулевому индексу? - PullRequest
2 голосов
/ 12 ноября 2009

В моем коде я могу ссылаться на столбец, используя его индекс. Но я бы предпочел использовать это имя. Это возможно? Я понятия не имею. : D

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="800">   

<Grid ShowGridLines="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition x:Name="LeftColumn" Width="200"></ColumnDefinition>
        <ColumnDefinition x:Name="MiddleColumn" Width="200"></ColumnDefinition>
        <ColumnDefinition x:Name="RightColumn" Width="*"></ColumnDefinition>
    </Grid.ColumnDefinitions>

    <Button x:Name="WelcomeButton" Grid.Column="1">Click me.</Button> //Here!
</Grid>

Edit:

Если нет возможности ссылаться на него по имени, какой смысл использовать для указания имени столбца? (Я новичок в WPF: P)

Ответы [ 3 ]

4 голосов
/ 12 ноября 2009

Да! Прелесть WPF в том, насколько просто добавить нужные функции. Вы можете легко добавить именованные строки сетки и столбцы, используя прикрепленные свойства. Например, приведенный ниже код позволит вам сделать это:

<Grid ShowGridLines="True">
  <Grid.ColumnDefinitions>
    <ColumnDefinition x:Name="LeftColumn" Width="200" />
    <ColumnDefinition x:Name="MiddleColumn" Width="200" />
    <ColumnDefinition x:Name="RightColumn" Width="*" />
  </Grid.ColumnDefinitions>
  <Button my:Grid_Named.Column="RightColumn">Click me.</Button>
</Grid>

Вот сам код. Это довольно просто и заняло всего несколько минут, чтобы написать:

public static class Grid_Named
{
  // Define Grid_Name.Column property
  public static string GetColumn(DependencyObject obj) { return (string)obj.GetValue(ColumnProperty); }
  public static void SetColumn(DependencyObject obj, string value) { obj.SetValue(ColumnProperty, value); }
  public static readonly DependencyProperty ColumnProperty = DependencyProperty.RegisterAttached("Column", typeof(string), typeof(Grid_Named), new UIPropertyMetadata
  {
    PropertyChangedCallback = (obj, e) =>
      {
        if(e.OldValue!=null) BindingOperations.ClearBinding(obj, Grid.ColumnProperty);
        if(e.NewValue!=null) BindingOperations.SetBinding(obj, Grid.ColumnProperty, _columnBinding);
      },
  });

  // Define Grid_Named.Row property
  public static string GetRow(DependencyObject obj) { return (string)obj.GetValue(RowProperty); }
  public static void SetRow(DependencyObject obj, string value) { obj.SetValue(RowProperty, value); }
  public static readonly DependencyProperty RowProperty = DependencyProperty.RegisterAttached("Row", typeof(string), typeof(Grid_Named), new UIPropertyMetadata
  {
    PropertyChangedCallback = (obj, e) =>
    {
      if(e.OldValue!=null) BindingOperations.ClearBinding(obj, Grid.RowProperty);
      if(e.NewValue!=null) BindingOperations.SetBinding(obj, Grid.RowProperty, _rowBinding);
    },
  });

  // Construct bindings for Grid.Column and Grid.Row
  private static BindingBase _columnBinding = BuildBinding(grid => grid.ColumnDefinitions, ColumnProperty);
  private static BindingBase _rowBinding = BuildBinding(grid => grid.RowDefinitions, RowProperty);
  private static BindingBase BuildBinding(Func<Grid, IList> getDefinitions, DependencyProperty nameProperty)
  {
    var binding = new MultiBinding
    {
      Converter = new NameLookupConverter { GetDefinitions = getDefinitions }
    };
    binding.Bindings.Add(new Binding { Path = new PropertyPath(nameProperty), RelativeSource = RelativeSource.Self });
    binding.Bindings.Add(new Binding { RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(Grid), 1) });
    return binding;
  }

  // Converter to take a row/column name and a Grid, and find the index of that row/column in the grid
  private class NameLookupConverter : IMultiValueConverter
  {
    public Func<Grid, IList> GetDefinitions;

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
      var name = values[0] as string;
      var grid = values[1] as Grid;

      if(grid==null || name==null) return 0;

      object namedObject = grid.FindName(name);
      if(namedObject==null) return 0;

      int index = GetDefinitions(grid).IndexOf(namedObject);
      return index<0 ? 0 : index;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
      throw new NotImplementedException();
    }
  }
}

Как видите, каждый раз, когда вы добавляете присоединенное свойство Grid_Named.Column или Grid_Named.Row, оно просто создает привязку для Grid.Column или Grid.Row, которая использует IMultiValueConveter для выбора соответствующего номера столбца или строки.

Просто, нет?

0 голосов
/ 12 ноября 2009

Нет, это невозможно. Имя здесь для доступа к нему в коде, так что вы можете изменить его размер или связать его с другими элементами xaml, чтобы изменить его размер во время выполнения.

0 голосов
/ 12 ноября 2009

Нет, это не так.

Если вы действительно хотите, вы можете написать собственный ValueConverter или прикрепленное свойство, чтобы подделать его, но я бы не рекомендовал его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...