Дочерний элемент управления, блокирующий обработчик событий родителя

#wpf #wpf-controls

#wpf #wpf-элементы управления

Вопрос:

У меня есть пользовательский элемент управления, в котором зарегистрирован обработчик событий MouseDown. Пользовательский элемент управления содержит средство просмотра прокрутки с ItemsControl и TextBlock. Видимость ItemsControl и TextBlock переключается обработчиком событий MouseDown, поэтому одновременно виден только один из них. Обработчик событий вызывается правильно, когда я нажимаю на текстовый блок, но не в ItemsControl.

Если я установлю для параметра «IsHitTestVisible» в ItemsControl значение false, обработчик событий представления будет открыт, но я не смогу прокручивать.

Кто-нибудь может предложить выход, пожалуйста?

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

 <Grid>
 <Border>
  <ScrollViewer>
   <TextBlock>
  </ScrollViewer>
 <Border>
 <Border>
  <Grid>
   <ItemsControl/> <!-- Has a ScrollViewer in template to show scroll bar -->
  </Grid>
 <Border>
</Grid>
  

Ответ №1:

Ваш сценарий пользовательского интерфейса звучит для меня довольно странно, но если вы все еще хотите его реализовать, вы можете сделать следующее. Вы не получаете событие, вызванное для paren, потому что ItemsControl помечает его как обработанное, поэтому оно не направляется дальше. Вы можете подписаться на событие PreviewMouseDown вместо MouseDown в родительском элементе. Тогда независимо от того, что родительский элемент получит уведомление раньше, чем дочерние элементы.

Обновить

Вы можете сделать следующее

 <ScrollViewer>
    <Grid MouseDown="HandleMouseDown">
        <TextBlock />
        <ItemsControl IsHitTestVisible="false"/>
    </Grid>
</ScrollViewer>
  

Таким образом, у вас будет прокрутка для текстового блока и для элементов. Собственные полосы прокрутки ItemsControl использоваться не будут.

ОБНОВЛЕНИЕ 2

Если вы хотите иметь отдельные средства просмотра прокрутки, то другой возможностью может быть следующее (хотя я думаю, что некоторые границы и сетки действительно не нужны. Только если они функционируют в вашем фрагменте)

   <Grid>
    <Border>
      <ScrollViewer>
        <TextBlock MouseDown="HandleMouseDown">
      </ScrollViewer>
    <Border>
    <Border>
      <Grid>
        <ScrollViewer>
          <Grid MouseDown="HandleMouseDown">
            <ItemsControl IsHitTestVisible="false"/>
          </Grid>
        </ScrollViewer>
      </Grid>
    <Border>
  </Grid>
  

Комментарии:

1. Проблема с этим заключается в том, что как только я касаюсь полосы прокрутки в ItemsControl, вызывается обработчик событий. Я могу прокручивать ItemsControl только с помощью колесика мыши.

2. @Krishter: то есть вы хотите вести себя одним образом при нажатии на содержимое ItemsContol и другим способом при нажатии на полосу прокрутки? Если это так, я вижу только способ использования отдельного ScrollView.

3. Можете ли вы подробнее объяснить, почему вы находите это странным?

4. @alpha-mouse: Я добавил фрагмент кода к вопросу. TextBlock и ItemsControl переключаются с помощью привязки данных. Я не понимаю, где вы предлагаете мне добавить scrollviewer.

5. Хм. Я не смог представить, как эти элементы управления, исчезающие при щелчке мыши, могут выглядеть дружелюбно для пользователя. Но теперь я вижу, как это может быть полезно. Я отредактирую свой ответ для возможного решения.