В приведенном ниже примере у меня есть UserControl, который устанавливает один источник изображения для отображения в своем конструкторе, а затем использует его обработчик события Loaded для установки другого источника изображения.Когда я использую этот элемент управления в качестве Visual для VisualBrush, используемого в качестве OpacityMask, заданного с помощью Style и / или Style Trigger, я никогда не вижу вызываемого обработчика события Loaded.
Это четыре примера использования в кодениже.
Во-первых, пользовательский элемент управления используется сам по себе (и мы видим результат обработчика события Loaded).Это показывает, что сам элемент управления работает так, как описано.
Во-вторых, он используется в ближайшем простом примере к моему фактическому варианту использования в триггере в стиле для установки OpacityMask (результат события Loaded невидел).
В-третьих, OpacityMask указывается напрямую (виден результат события Loaded).Это показывает, что элемент управления можно использовать в качестве маски и при этом по-прежнему вызывать обработчик события Loaded.
В-четвертых, OpacityMask указывается с помощью стиля, но без триггера (и результат загруженного чётногоне видно).
Почему событие Loaded не запускается, когда этот элемент управления используется в стиле?Что я могу сделать, чтобы он сработал?
Несколько комментариев:
Событие Loaded используется аналогично LoadedBehavior MediaElement, чтобы перевести элемент управления в исходное состояние на основедля значений нескольких свойств зависимостей.
Я действительно проверял, что обработчик события Loaded на самом деле не вызывается в тех случаях, когда я не вижу результат.
Фактическое использованиеcase имеет сложный набор стилей и шаблонов, применяемых в ItemsControl.Было бы нецелесообразно переписать это, чтобы напрямую указать OpacityMask (в частности, триггеры предоставляют некоторые важные функции).
Мы можем использовать этот UserControl в качестве маски для любого другого элемента управления (например, TextBox), поэтому мымы не можем ожидать, что замаскированный элемент управления сделает что-либо, чтобы сообщить нашему элементу управления, что он загружен.
В наших целях событие Initialized срабатывает слишком рано (в частности, все свойства, установленные через XAML, еще не будут установлены,и в реальном случае нам нужно, чтобы эти свойства были установлены).
Кажется вероятным, что комментарий о VisualBrush.Visual является релевантным.Тем не менее, я думаю, что макет должен быть запущен на элементе управления при использовании внутри стиля - в противном случае отображение не произойдет, верно?
Однако корневой UIElement по существу изолирован от остальной частисистема;стили, раскадровки и внешний макет, определяемые родителем, к которому применяется кисть, не могут проникнуть через эту границу.Следовательно, вы должны явно указать размер корневого UIElement, потому что его единственным родителем является VisualBrush и, следовательно, он не может автоматически изменять размер для окрашиваемой области.Дополнительные сведения о макете в Windows Presentation Foundation (WPF) см. В разделе Макет.
XAML UserControl:
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Loaded="UserControl1_OnLoaded">
<Image Width="791" Height="119">
<Image.Style>
<Style TargetType="Image">
<Setter Property="Source">
<Setter.Value>
<Binding Path="CurrentImagePath" RelativeSource="{RelativeSource AncestorType=local:UserControl1}" />
</Setter.Value>
</Setter>
</Style>
</Image.Style>
</Image>
</UserControl>
и код пользователя UserControl:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
CurrentImagePath = "pack://application:,,,/Resources/SampSeq_0000.png";
}
public string CurrentImagePath
{
get { return (string)GetValue(CurrentImagePathProperty); }
protected set { SetValue(CurrentImagePathProperty, value); }
}
public static readonly DependencyProperty CurrentImagePathProperty =
DependencyProperty.Register("CurrentImagePath", typeof(string), typeof(UserControl1),
new UIPropertyMetadata(string.Empty, null, null));
private void UserControl1_OnLoaded(object sender, RoutedEventArgs e)
{
CurrentImagePath = "pack://application:,,,/Resources/SampSeq_0002.png";
}
}
и, наконец, в четырех примерах используется:
<Window x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="750" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- usage of the control by itself -->
<local:UserControl1 Grid.Row="0" />
<CheckBox Grid.Row="1" x:Name="checkBox" Content="mask?" IsChecked="False"/>
<!-- usage of the control as a triggered opacity mask -->
<Rectangle Grid.Row="2" Width="791" Height="119" Fill="BlueViolet">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="OpacityMask" Value="{x:Null}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsChecked, ElementName=checkBox}" Value="True">
<Setter Property="OpacityMask">
<Setter.Value>
<VisualBrush>
<VisualBrush.Visual>
<local:UserControl1 />
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Rectangle.Style>
</Rectangle>
<!-- usage of the control as a directly specified OpacityMask -->
<Rectangle Grid.Row="3" Width="791" Height="119" Fill="OrangeRed">
<Rectangle.OpacityMask>
<VisualBrush>
<VisualBrush.Visual>
<local:UserControl1 />
</VisualBrush.Visual>
</VisualBrush>
</Rectangle.OpacityMask>
</Rectangle>
<!-- usage of the control in OpacityMask applied with a style but without triggers-->
<Rectangle Grid.Row="4" Width="791" Height="119" Fill="DarkGreen">
<Rectangle.Style>
<Style TargetType="Rectangle">
<Setter Property="OpacityMask">
<Setter.Value>
<VisualBrush>
<VisualBrush.Visual>
<local:UserControl1 />
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</Style>
</Rectangle.Style>
</Rectangle>
</Grid>
</Window>
Два примера изображений, которые я использовал:
![SampSeq_0001.png](https://i.stack.imgur.com/5Y6B3.png)