Я согласен с вашим редактированием. Мне бы очень хотелось знать, что происходит и как я могу заставить этот чертов шаблон работать так, как предполагалось ...: /
дачен этим:
Я сделал очень простой пример:
MainWindow.xaml:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="RichTextBox">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="RichTextBox">
<Grid Height="100" Width="200">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Background="Blue" Grid.Row="0">Label</Label>
<Border PreviewMouseDown="Border_PreviewMouseDown" Background="Red" Grid.Row="1">
<ScrollViewer x:Name="PART_ContentHost" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<RichTextBox>
<FlowDocument>
<FlowDocument.Blocks>
<Paragraph>
oaizeropiazuerpoaizeurpoaizeurpaozieurpaozieru
</Paragraph>
</FlowDocument.Blocks>
</FlowDocument>
</RichTextBox>
</Grid>
</Window>
MainWindow.xaml.cs:
using System.Diagnostics;
using System.Windows;
using System.Windows.Input;
namespace Test
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Border_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("Click !");
}
}
}
Теперь, когда я явно помещаю PreviewMouseDown EventHandler в Border, а не в метку в моем шаблоне, я ожидаю, что он будет срабатывать при нажатии на (красную) границу элемента управления, но не когда я нажимаю на (синий) этикетка.
Тем не менее, событие запускается, когда я нажимаю на (красную) границуА ТАКЖЕ когда я нажимаю на (синий) ярлык.
так почему же Label вызывает EventHandler, который я явно прикрепил к другой части шаблона controlTemplate (т.е. границы)?
Я проверил: если я удаляюPreviewMouseDown="Border_PreviewMouseDown"
код из свойств границы, событие больше не запускается на этикетке.
что мне здесь не хватает?
и что бы правильно сделать? Как я могу спроектировать свой controlTemplate таким образом, чтобы событие PreviewMouseDown запускалось только частью элемента шаблонного элемента управления?
заранее спасибо
Редактировать: следуя ответу Snowbear, я проверял исходный источник события, когда нажимал на ярлык. Это действительно граница. Почему это так? каким образом граница инкапсулирует метку в шаблоне выше? Я специально установил их на разных строках сетки, чтобы избежать этого, так как получится?
Edit2 Просто для удовольствия, я создал обработчик, который печатает только отправителя / источника / оригинального источника события, и я прикрепил его в шаблоне к сетке, границе и просмотрщику прокрутки.
Вот что я получаю, когда нажимаю ОДИН РАЗ (и только один раз) на вертикальной полосе прокрутки, например:
Clic -- Sender: System.Windows.Controls.Grid -- OriginalSource: Microsoft.Windows.Themes.ScrollChrome -- Source: MyRichTextBox
Clic -- Sender: System.Windows.Controls.Border -- OriginalSource: Microsoft.Windows.Themes.ScrollChrome -- Source: MyRichTextBox
Clic -- Sender: System.Windows.Controls.ScrollViewer -- OriginalSource: Microsoft.Windows.Themes.ScrollChrome -- Source: MyRichTextBox
Clic -- Sender: System.Windows.Controls.Grid -- OriginalSource: Microsoft.Windows.Themes.ScrollChrome -- Source: System.Windows.Controls.ScrollViewer
Clic -- Sender: System.Windows.Controls.Border -- OriginalSource: Microsoft.Windows.Themes.ScrollChrome -- Source: System.Windows.Controls.ScrollViewer
Clic -- Sender: System.Windows.Controls.ScrollViewer -- OriginalSource: Microsoft.Windows.Themes.ScrollChrome -- Source: System.Windows.Controls.ScrollViewer
это ясно решает проблему: событие по какой-то причине действительно туннелируется дважды: сначала с TemplatedParent (то есть с RichtextBox) в качестве источника, а затем с contentPresenter (то есть с ScrollViewer) в качестве источника.
Из-за самых мешковатых штанов Мерлина, мне действительно интересно, что случилось с главой MS Dev, которая запрограммировала это ...