简体   繁体   中英

WPF: Making Properties of embedded control from template in custom control available

I have a Custom Control IconMD with the Properties IconName , OverlayName and OverlayPosition

I have embedded this Control in another Custom Control IconButton like so:

<ControlTemplate TargetType="{x:Type local:IconButton}">
    <Border 
        Background="{TemplateBinding Background}"
        BorderBrush="{TemplateBinding BorderBrush}"
        BorderThickness="{TemplateBinding BorderThickness}">
        <Border.Style>
            <Style TargetType="{x:Type Border}">
                <Setter Property="Opacity" Value="0.7"/>
                <Style.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Opacity" Value="1"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Border.Style>
        <Grid>
            <local:IconMD
                x:Name="_ButtonIcon"
                OverlayPosition="{TemplateBinding OverlayPosition}"
                IconName="{TemplateBinding IconName}"
                OverlayName="{TemplateBinding OverlayIconName}"
            />
        </Grid>
    </Border>
</ControlTemplate>

The only purpose of the Dependency Properties OverlayPosition , IconName and OverlayIconName of this IconButton Control are simply to be passed through to the embedded Icon - the same idea as BorderBrush etc.

Now, as I also have IconToggleButton and IconRepeatButton (which inherit from the respective Base Classes and cannot inherit from IconButton !?), i must repeat this pattern for each of them. Should the capabilities of my IconMD Class grow, i would have to expand this pattern in every Custom Control that uses it.

How can I simply make the (properties of the) named IconMD Control "_ButtonIcon" available outside of my IconButton ?

I would imagine instead of this

<imCC:IconButton
    IconName="mdi-account-card-details"
    OverlayIconName="mdi-multiplication-box"/>

writing something like this

<imCC:IconButton
    _ButtonIcon.IconName="mdi-account-card-details"
    _ButtonIcon.OverlayName="mdi-multiplication-box"/>

You could define the properties as attached properties that you can set on any UIElement or Button element.

Attached Properties Overview: https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/attached-properties-overview

namespace WpfApplication1
{
    public static class AttachedProperties
    {
        public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
            "IconName", typeof(string), typeof(AttachedProperties));

        public static void SetIconName(UIElement element, string value)
        {
            element.SetValue(IsBubbleSourceProperty, value);
        }
        public static string GetIconName(UIElement element)
        {
            return (string)element.GetValue(IsBubbleSourceProperty);
        }
    }
}

<imCC:IconButton xmlns:local="clr-namespace:WpfApplication1"
    local:AttachedProperties.IconName="mdi-account-card-details" />

You can use attached properties instead of normal dependency properties (create in visual studio with snipped propa ).

If you create IconName as attached property in class IconButton , you set it as follows:

<imCC:IconButton
    imCC:IconButton.IconName="mdi-account-card-details"
    ...

And use in the ControlTemplate like this:

<local:IconMD
    x:Name="_ButtonIcon"
    IconName="{Binding Path=(local:IconButton.IconName),RelativeSource={RelativeSource TemplatedParent}}"
    ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM