Как получить информацию о строке и столбце из метки внутри сетки в WPF? - PullRequest
1 голос
/ 21 февраля 2011

У меня есть сетка 3х3, которую я использую как игровую доску для крестиков.Каждая сетка имеет метку, которая может отображать «X», «O» или «».Каждая из этих меток содержит информацию о строках и столбцах, в которой они расположены.Я пытаюсь получить эту информацию из файла кода.Пока у меня есть:

        <Label Grid.Row="0" Grid.Column="0" Name="lblZeroxZero" MouseDown="lblZeroxZero_MouseDown" FontSize="72" Padding="5" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
    <Label Grid.Row="0" Grid.Column="1" Name="lblZeroxOne" MouseDown="lblZeroxOne_MouseDown" FontSize="72" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" />
    <Label Grid.Row="0" Grid.Column="2" Name="lblZeroxTwo" MouseDown="lblZeroxTwo_MouseDown" VerticalContentAlignment="Center" FontSize="72" HorizontalContentAlignment="Center" />
    <Label Grid.Row="1" Grid.Column="0" Name="lblOnexZero" MouseDown="lblOnexZero_MouseDown" HorizontalContentAlignment="Center" FontSize="72" VerticalContentAlignment="Center" />
    <Label Grid.Row="1" Grid.Column="1" Name="lblOnexOne" MouseDown="lblOnexOne_MouseDown" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" FontSize="72" />
    <Label Grid.Row="1" Grid.Column="2" Name="lblOnexTwo" MouseDown="lblOnexTwo_MouseDown" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" FontSize="72" />
    <Label Grid.Row="2" Grid.Column="0" Name="lblTwoxZero" MouseDown="lblTwoxZero_MouseDown" FontSize="72" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" />
    <Label Grid.Row="2" Grid.Column="1" Name="lblTwoxOne" MouseDown="lblTwoxOne_MouseDown" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" FontSize="72" />
    <Label Grid.Row="2" Grid.Column="2" Name="lblTwoxTwo" MouseDown="lblTwoxTwo_MouseDown" VerticalContentAlignment="Center" HorizontalContentAlignment="Center" FontSize="72">

Это мои метки, и в моем файле кода я хочу получить информацию Grid.Row и Grid.Column.Когда я набираю lblZeroxZero.intellisense не вызывает никаких свойств, которые содержат информацию о строках и столбцах.Кто-нибудь знает, как получить эту информацию?Нужно ли обращаться к нему из таблицы данных, а не к метке?

Редактировать: Дополнительная информация

В моем кодовом файле у меня есть этот метод (еще не завершен)

    private int[] GetLabelPosition(Label lbl)
    {
        int[] rowColumnInfo = new int[2];
        if (lbl.Name == "lblZeroxZero")
        {
            rowColumnInfo[0] = 0;
            rowColumnInfo[1] = 0;                
        }
        else if (lbl.Name == "lblOnexZero")
        {
            rowColumnInfo[0] = 1;
            rowColumnInfo[1] = 0;
        }
        return rowColumnInfo;
    }

В настоящее время единственный способ узнать, как получить информацию о строке и столбце ярлыка, - посмотреть его имя.Я хотел бы получить информацию Grid.Row и Grid.Column, не создавая кучу конкретных случаев для каждого имени метки.

Ответы [ 3 ]

3 голосов
/ 21 февраля 2011

Используйте вложенные свойства GetRow и GetColumn при Grid.Пример

int row = Grid.GetRow(lblZeroxZero);
int column = Grid.GetColumn(lblZeroxZero);

Обновление

В вашем случае вы можете сделать что-то вроде

private int[] GetLabelPosition(Label lbl)
{
    return new int[] { Grid.GetRow(lbl), Grid.GetColumn(lbl) };
}
1 голос
/ 21 февраля 2011

Как предположил OJ, вам следует использовать привязку данных. Это позволяет отделить проблему представления игры на экране от проблемы управления внутренней логикой игры.

Вам потребуется создать класс Cell, который предоставляет свойства Row, Column и Owner. Класс должен будет реализовать INotifyPropertyChanged, чтобы при изменении Owner он мог предупреждать пользовательский интерфейс, вызывая событие PropertyChanged. Наконец, класс будет реализовывать SelectCellCommand, который будет правильно устанавливать Owner для ячейки при ее выполнении (а свойство CanExecute будет установлено в значение false, как только будет установлен владелец ячейки).

Вы создадите коллекцию, содержащую девять из этих Cell s, со свойствами Row, Column и Owner, для которых установлены соответствующие начальные значения. Вся ваша игровая логика (например, чья это очередь? Кто-то победил?) Изучит эту коллекцию.

В пользовательском интерфейсе вы создадите ItemsControl, привязанный к коллекции Cell s. Каждый элемент в элементе управления будет ячейкой в ​​сетке.

Вы установите ItemsPanel на Grid, который скажет ItemsControl, как раскладывать свои предметы. Вы создадите ItemContainerStyle, который назначит вложенные свойства Grid.Row и Grid.Column контейнерам элементов - ItemsControl создаст ItemsPresenter для каждого объекта в ItemsSource, а Grid.Row и Grid.Column свойства должны быть установлены для этого объекта, чтобы Grid мог видеть их и знать, куда их поместить.

Наконец, элемент управления будет содержать ItemTemplate, который описывает, как должен отображаться каждый элемент. Я использую Button (так как вы хотите, чтобы была команда, которая выполняется, когда пользователь нажимает на нее), которая содержит TextBlock, который отображает X или O в Owner.

Это может выглядеть примерно так:

<ItemsControl ItemsSource="{Binding {StaticResource Cells}}">
   <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
         <Grid>
            <Grid.ColumnDefinitions>
               <ColumnDefinition/>
               <ColumnDefinition/>
               <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
               <RowDefinition/>
               <RowDefinition/>
               <RowDefinition/>
            </Grid.RowDefinitions>
         </Grid>
      </ItemsPanelTemplate>
      <ItemsPanel.ItemContainerStyle>
         <Style TargetType="ItemPresenter">
            <Setter Property="Grid.Column" Value="{Binding Column}"/>
            <Setter Property="Grid.Row" Value="{Binding Row}"/>
         </Style>
      </ItemsPanel.ItemContainerStyle>
      <ItemsPanel.ItemTemplate>
         <DataTemplate DataType="local:Cell">
            <Button Command="{Binding SelectCellCommand}" VerticalContentAlignment="Center" HorizontalContentAlignment="Center">
               <TextBlock FontSize="72" Source="{Binding Owner}"/>
            </Button>                   
         </DataTemplate>
      </ItemsPanel.ItemTemplate>
   </ItemsControl>
</ItemsControl>

Зачем все это проходить?

Хорошо, давайте посмотрим на проблемы, с которыми сталкивается ваш текущий дизайн:

  1. Если вы хотите изменить расположение ячеек в вашем дизайне, у вас есть девять различных элементов управления, которые нужно исправить. Здесь вы просто меняете DataTemplate для ячеек.

  2. Нет необходимости в девяти различных обработчиках событий. Поскольку кнопки привязаны к объектам команд, которые являются свойствами Cell, вам не нужно реализовывать какой-либо способ определения ячейки, по которой пользователь только что щелкнул, - команда - это . Кроме того, вы можете отключить команду (и ее кнопку) очень просто после установки Owner.

  3. Вся ваша игровая логика может смотреть на простую структуру данных - набор Cell объектов - не заботясь о том, как работает пользовательский интерфейс.

Наконец, и самое главное, привязка данных - это ядро ​​разработки приложений WPF. Это делает разработку приложений WPF гораздо проще, чем реализацию приложений WinForms. Если вы изучаете WPF без обучения связыванию, вы теряете время.

0 голосов
/ 21 февраля 2011

+ 1 за первый ответ Мелека, но я также хотел бы предложить, чтобы вместо использования codebehind, почему бы вам не использовать привязку данных?Это значительно упростит ваш код.

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