Гость
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / RoutedEvents / 9 сообщений из 9, страница 1 из 1
03.10.2020, 19:29
    #40005162
felix_ff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RoutedEvents
У меня тут вечер занимательного программирования :)

Что за фигня:
имеем такую разметку
xaml
<Window x:Class="WPFANI.MainWindow"
xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d=" http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc=" http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFANI"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" UIElement.MouseDown="OnMouseDown" >
<Grid IsHitTestVisible="True">
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Menu x:Name="main_menu" Grid.Row="0" ItemsSource="{Binding AllObjects}" IsHitTestVisible="True"/>
<Frame x:Name="main_frame" Grid.Row="1">
<Frame.Content>
<ListBox x:Name="log"/>
</Frame.Content>
</Frame>
<Button Grid.Row="2" Content="Clear" Width="75" Margin="10,0,707,0" Click="Button_Click"/>
</Grid>
</Window>


код окна
MainWindow
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
 public partial class MainWindow : Window
    {
        public ObservableCollection<string> AllObjects { get; }
        public MainWindow()
        {
            InitializeComponent();
            AllObjects = new ObservableCollection<string>();
            DataContext = this;

            AllObjects.Add("menu1");
            AllObjects.Add("menu2");

            
        }

        private void OnPreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            var orig = e.OriginalSource.GetType().Name;
            var sour = e.Source.GetType().Name;
            log.Items.Add(string.Format("PreviewMouseDown o:{0}       s:{1}", orig, sour));
            
        }

        private void OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            var orig = e.OriginalSource.GetType().Name;
            var sour = e.Source.GetType().Name;
            log.Items.Add(string.Format("             MouseDown o:{0}       s:{1}", orig, sour));
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            log.Items.Clear();
        }
    }
}




Я предполагал что аттачед-событие типа UIElement при нажатии на MenuItem должно маршрутизироваться в виде:
MouseDown o:TextBlock s:TextBlock
MouseDown o:TextBlock s:ContentPresenter
MouseDown o:TextBlock s:Grid
MouseDown o:TextBlock s:Border
MouseDown o:TextBlock s:MenuItem
и.т.д вверх по визуальному дереву.

Но тут какая то джигурда оно вообще не отрабатывает при нажатии MenuItem элемента.
Он же наследник UIElement какого хрена оно не всплывает?





ps
кстати кто нибудь подскажет как в тэге "src" сделать выделение куска текста цветом?
а то spoiler глаза режет
...
Рейтинг: 0 / 0
03.10.2020, 19:44
    #40005166
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RoutedEvents
felix_ff
кстати кто нибудь подскажет как в тэге "src" сделать выделение куска текста цветом?
а то spoiler глаза режет
FAQ
ну и для оформления XAML очевидно нужно использовать тэг XML
...
Рейтинг: 0 / 0
03.10.2020, 21:18
    #40005192
felix_ff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RoutedEvents
Shocker.Pro,

не работает

Код: sql
1.
<test>тэг [src] вот тест нужно выделить этот кусок </test>




Код: xml
1.
<test>тэг [src xml] вот тест нужно >>>выделить этот кусок<<< </test>





хотя если опустить раскраску xaml то в целом наверное репрезентативно. Shocker.Pro спасибо.

из-изначального поста
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
<Window x:Class="WPFANI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFANI"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" UIElement.MouseDown="OnMouseDown" >
<Grid IsHitTestVisible="True">
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Menu x:Name="main_menu" Grid.Row="0" ItemsSource="{Binding AllObjects}" IsHitTestVisible="True"/>
<Frame x:Name="main_frame" Grid.Row="1">
<Frame.Content>
<ListBox x:Name="log"/>
</Frame.Content>
</Frame>
<Button Grid.Row="2" Content="Clear" Width="75" Margin="10,0,707,0" Click="Button_Click"/>
</Grid>
</Window>


...
Рейтинг: 0 / 0
05.10.2020, 07:31
    #40005358
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RoutedEvents
felix_ff,
MSDNThe MenuItem handles the MouseDown event, so if you attach an event handler to MouseDown, your handler will never be called. To add your own handler, subscribe to the PreviewMouseDown event or subscribe to MouseDown by calling AddHandler(RoutedEvent, Delegate, Boolean) with handledEventsToo set to true.
https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.menuitem?view=netcore-3.1
...
Рейтинг: 0 / 0
05.10.2020, 07:54
    #40005361
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RoutedEvents
-
...
Рейтинг: 0 / 0
05.10.2020, 14:54
    #40005456
felix_ff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RoutedEvents
Сон Веры Павловны,

Все равно несколько странно:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
 public MainWindow()
        {
            InitializeComponent();
            AllObjects = new ObservableCollection<string>();
            DataContext = this;

            AllObjects.Add("menu1");
            AllObjects.Add("menu2");

            var handler = new MouseButtonEventHandler((o, e) => {
                var obj = o.GetType().Name;
                var orig = e.OriginalSource.GetType().Name;
                var sour = e.Source.GetType().Name;
                var mm = (e.OriginalSource is MenuItem) ? ((MenuItem)e.OriginalSource).Name : "none";
                log.Items.Add(string.Format("       MouseDown obj:{0}  orig:{1}       source:{2}  Handled:{3} MenuItem:{4}", obj, orig, sour, e.Handled, mm));
                e.Handled = false;
               
            });

            AddHandler(MouseDownEvent, handler, true);
}

  private void Button_Click(object sender, RoutedEventArgs e)
        {
            log.Items.Clear();
        }



Код: xml
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
<Window x:Class="WPFANI.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:ig="http://WINAPI"
        mc:Ignorable="ig" 
        xmlns:local="clr-namespace:WPFANI"
        Title="MainWindow" Height="450" Width="800">
    <Grid >
        <Grid.RowDefinitions>
            <RowDefinition Height="24"/>
            <RowDefinition/>
            <RowDefinition Height="20"/>
        </Grid.RowDefinitions>
        <Menu x:Name="main_menu" Grid.Row="0" ItemsSource="{Binding AllObjects}" />
        <Frame x:Name="main_frame" Grid.Row="1">
            <Frame.Content>
                <ListBox x:Name="log"/>
            </Frame.Content>
        </Frame>
        <Button Grid.Row="2" Content="Clear" Margin="10,3,725,1" Click="Button_Click" Padding="1,0" FontWeight="SemiBold" TextOptions.TextFormattingMode="Display"/>
    </Grid>
</Window>




При нажатии на кнопку MenuItem в лог пишется:
MouseDown obj:MainWindow orig:TextBlock source:MenuItem Handled:True MenuItem:none

Видимо я неправильно понимаю устройство системы маршрутизации ибо
я ожидал что будет куча строк ведь почти каждый элемент является наследником UIElement.

Handled мы явно устанавливаем в false, да и AddHandler применяем c handledEventsToo = true;
Обработчик срабатывает один раз?
...
Рейтинг: 0 / 0
05.10.2020, 17:55
    #40005532
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RoutedEvents
felix_ff
я ожидал что будет куча строк ведь почти каждый элемент является наследником UIElement.

Обработчик события в данном случае только один, и он почти на самой верхушке визуального дерева - на окне, все элементы вниз по структуре визуального дерева обработчика не имеют, и просто пробрасывают событие дальше вверх. Ни AddHandler, ни просто установка MouseDown в xaml-разметке не вешают обработчики на всю иерархию дерева, они вешают обработчик ровно на то, что указано - на окно. Он и отрабатывает один раз, когда положено. Я с трудом могу представить, зачем вышеприведенное может понадобиться на практике, но если целью является просто посмотреть, как всплывает событие, то можно пройтись вверх по визуальному дереву самому, и прицепить обработчик ко всему, что попадётся:
Код: xml
1.
2.
3.
<Menu>
  <MenuItem Header="Foo" x:Name="Foo" />
</Menu>


Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
public partial class MainWindow
{
  public MainWindow()
  {
    InitializeComponent();
    Loaded += MainWindow_Loaded;
  }

  private void MainWindow_Loaded(object sender, RoutedEventArgs e)
  {
    UIElement current = Foo;
    while(current!=null)
    {
      current.AddHandler(MouseDownEvent, (MouseButtonEventHandler)MainWindow_OnMouseDown, true);
      Console.WriteLine("Handler attached to {0}", current);
      current = VisualTreeHelper.GetParent(current) as UIElement;
    }
  }

  void MainWindow_OnMouseDown(object sender, MouseButtonEventArgs e)
  {
    Console.WriteLine("{0} / {1} / {2}",
      sender,
      e.Source,
      e.OriginalSource
    );
  }
}


Тогда в консольном выводе будет вот такое:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
Handler attached to System.Windows.Controls.MenuItem Header:Foo Items.Count:0
Handler attached to System.Windows.Controls.WrapPanel
Handler attached to System.Windows.Controls.ItemsPresenter
Handler attached to System.Windows.Controls.Border
Handler attached to System.Windows.Controls.Menu Items.Count:1
Handler attached to System.Windows.Controls.ContentPresenter
Handler attached to System.Windows.Documents.AdornerDecorator
Handler attached to System.Windows.Controls.Border
Handler attached to wpftest2.MainWindow

- после загрузки окна, и
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
System.Windows.Controls.MenuItem Header:Foo Items.Count:0 / System.Windows.Controls.MenuItem Header:Foo Items.Count:0 / System.Windows.Controls.TextBlock
System.Windows.Controls.WrapPanel / System.Windows.Controls.WrapPanel / System.Windows.Controls.TextBlock
System.Windows.Controls.ItemsPresenter / System.Windows.Controls.ItemsPresenter / System.Windows.Controls.TextBlock
System.Windows.Controls.Border / System.Windows.Controls.ItemsPresenter / System.Windows.Controls.TextBlock
System.Windows.Controls.Menu Items.Count:1 / System.Windows.Controls.MenuItem Header:Foo Items.Count:0 / System.Windows.Controls.TextBlock
System.Windows.Controls.ContentPresenter / System.Windows.Controls.ContentPresenter / System.Windows.Controls.TextBlock
System.Windows.Documents.AdornerDecorator / System.Windows.Controls.ContentPresenter / System.Windows.Controls.TextBlock
System.Windows.Controls.Border / System.Windows.Controls.ContentPresenter / System.Windows.Controls.TextBlock
wpftest2.MainWindow / System.Windows.Controls.MenuItem Header:Foo Items.Count:0 / System.Windows.Controls.TextBlock

- при клике по MenuItem
...
Рейтинг: 0 / 0
05.10.2020, 19:31
    #40005541
felix_ff
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RoutedEvents
Сон Веры Павловны,

Догнал, большое спасибо
...
Рейтинг: 0 / 0
06.10.2020, 07:29
    #40005594
Roman Mejtes
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
RoutedEvents
Код: c#
1.
2.
3.
4.
5.
EventManager.RegisterClassHandler(typeof(FrameworkElement), Mouse.MouseDownEvent, new RoutedEventHandler(OnMouseDown), true);
public static void OnMouseDown(object sender, RoutedEventArgs arg)
{
      Debug.Print($"Sender: {sender.GetType()}, Source: {arg.Source}");
}


можно вот так, глобально :D
...
Рейтинг: 0 / 0
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / RoutedEvents / 9 сообщений из 9, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]