WPF - при наведении курсора на один элемент отображается содержимое в другом элементе - PullRequest
3 голосов
/ 24 апреля 2009

Я хотел бы добиться эффекта, благодаря которому я могу навести курсор на кнопку и сделать так, чтобы TextBlock обновлял ее содержимое (посредством привязки). Чтобы усложнить ситуацию, кнопка является одной из многих кнопок, определенных в ItemsControl / DataTemplate. TextBlock находится вне области ItemsControl.

Некоторая упрощенная разметка задачи выглядит следующим образом:

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition />
  </Grid.RowDefinitions>
  <ItemsControl Grid.Row="0">
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <Button Content="{Binding Title}"
                Command="{Binding Command}" />    
      </DataTemplate>
    </ItemsControl.ItemTemplate>
  </ItemsControl>
  <TextBlock x:Name="TitleTextBox" Grid.Row="1" />
</Grid>

Скажем, в этом примере я могу захотеть привязать свойство «Заголовок» элемента данных к свойству «Текст» TextBlock.

Я предполагаю, что хочу подключиться к кнопке IsMouseOver кнопки, но, похоже, не могу правильно ее подключить.

1 Ответ

4 голосов
/ 28 апреля 2009

Я не верю, что вы сможете достичь этого без некоторого кода ... однако вам не нужно использовать codebehind. «Поведение» вполне подойдет для этого (либо старое школьное прикрепленное поведение , либо более современное Blend Behavior ). Вот как может выглядеть измененная разметка при использовании прикрепленного поведения:

<Grid>
  <Grid.RowDefinitions>
    <RowDefinition />
    <RowDefinition />
  </Grid.RowDefinitions>
  <ItemsControl x:Name="Buttons" Grid.Row="0" ext:Hover.TrackChildItems="true">
    <ItemsControl.ItemTemplate>
      <DataTemplate>
        <Button Content="{Binding Title}"
                Command="{Binding Command}" />
      </DataTemplate>
    </ItemsControl.ItemTemplate>
  </ItemsControl>
  <TextBlock x:Name="TitleTextBox"
             Grid.Row="1"
             Text="{Binding ElementName=Buttons, Path=ext:Hover.Item.Content}" />
</Grid>

Здесь присоединенное поведение "Hover.TrackChildItems" используется для отслеживания соответствующих событий мыши и устанавливает доступное только для чтения свойство "Hover.Item" для элемента управления, над которым наведен курсор. Написание поведения должно быть достаточно простым и оставлено на ваше усмотрение.

Редактировать : чтобы настроить обработчики событий для элементов, первое, что нужно сделать, это просто и очевидно: перебрать элементы в свойстве Items и добавить обработчики.

Mouse.AddMouseEnter(item, OnMouseEnter);

Это прекрасно работает для статического содержимого, но динамическое (добавляемое и удаляемое во время выполнения) содержимое будет пропущено. Итак, затем вы должны отслеживать изменения в свойстве Items.

((INotifyCollectionChanged)Items).CollectionChanged += OnItemsChanged;

При необходимости добавляйте или удаляйте обработчики событий мыши, когда элементы добавляются и удаляются в обработчике CollectionChanged.

Есть и другое решение. Создайте для этого новый HoverTrackingItemsControl, полученный из ItemsControl. В этом элементе управления переопределите метод GetContainerForItemOverride, чтобы вернуть новый HoverTrackingItem, который обрабатывает MouseEnter / MouseLeave для уведомления родительского HoverTrackingItemsControl. Это решение, вероятно, проще реализовать, хотя оно требует специального элемента управления, тогда как решение Behavior является более общим и может использоваться с любым типом ItemsControl (ItemsControl, ListBox, ComboBox и т. Д.).

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