WPF - Ostrzeżenie przy bindowaniu koloru

0

Witam, mam następujący problem.
Próbuję bindować w swojej własnej kontrolce w WPF kolor, którego następnie używam by uzyskać efekt Hover.
Kod C# za to odpowiedzialny wygląda tak

public static readonly DependencyProperty HoverBrushProperty = DependencyProperty.Register("HoverBrush",typeof(Color),typeof(MaterialButton), new UIPropertyMetadata(Colors.White));
        public Color HoverBrush
        {
            get { return (Color)GetValue(HoverBrushProperty); }
            set { SetValue(HoverBrushProperty, value); }
        }

A binduję w sposób następujący

<Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="btnBorder" Property="Background">
                                <Setter.Value>
                                    <SolidColorBrush Color="{Binding Path=HoverBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
                                </Setter.Value>
                            </Setter>
 </Trigger>

I to proszę Państwa działa. Problem jednak widzi Visual Studio, które wyrzuca następujący komunikat:
Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=HoverBrush; DataItem=null; target element is 'SolidColorBrush' (HashCode=16157963); target property is 'Color' (type 'Color')

Zastanawiam się jak mógłbym pozbyć się tego komunikatu.
Próbowałem stosować się do zaleceń i zmieniać właściwość na SolidColorBrush - wtedy komunikaty znikały, ale nie działało to poprawnie.

0

Sprawdź tak:

Setter Property="Background" TargetName="myBorder">
                                                <Setter.Value>
                                                    <SolidColorBrush Color="{Binding HoverBrush, RelativeSource={RelativeSource FindAncestor, AncestorType=local:MyControl}}"/> 
                                                 </Setter.Value>
                                        </Setter>
0

@ali663
Niestety, ta zmiana nie psuje kodu, ale błąd zmienia się na następujący:
"Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='Materiality.WPF.Controls.MaterialButton', AncestorLevel='1''. BindingExpression:Path=HoverBrush; DataItem=null; target element is 'SolidColorBrush' (HashCode=21724664); target property is 'Color' (type 'Color')"

0

daj kod kontrolki

0

@ali663:

 <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:MaterialButton}">
                    <Border Opacity="1" Name="btnBorder" Background="{TemplateBinding Background}" CornerRadius="2">
                        <Border.Effect>
                            <DropShadowEffect Direction="-90" BlurRadius="10" ShadowDepth="1"/>
                        </Border.Effect>
                        <Grid>
                            <Border >   
                                <Border.Clip>
                                    <RectangleGeometry x:Name="rect">
                                        <RectangleGeometry.Rect>
                                            <MultiBinding Converter="{StaticResource Converter}">
                                                <Binding ElementName="btnBorder" Path="ActualWidth"/>
                                                <Binding ElementName="btnBorder" Path="ActualHeight"/>
                                            </MultiBinding>
                                        </RectangleGeometry.Rect>
                                    </RectangleGeometry>
                                </Border.Clip>
                                <local:Ripple Margin="-50"  ClipToBounds="True" HorizontalAlignment="Center"  VerticalAlignment="Center" RippleColor="{TemplateBinding RippleBrush}" x:Name="Ripple"/>
                            </Border>
                            <TextBlock FontSize="{TemplateBinding FontSize}" TextAlignment="Center" Padding="16,0,16,0" FontFamily="{StaticResource Roboto}" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{TemplateBinding Text}"/>
                        </Grid>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="btnBorder" Property="Background">
                                <Setter.Value>
                                    <SolidColorBrush Color="{Binding Path=HoverBrush, RelativeSource={RelativeSource TemplatedParent}}"/>
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="False">
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
0

Okej, już sobie poradziłem.
Dziękuje mimo wszystko za pomoc.
Propozycja @ali663 była trafna, potrzebowałem jednak jeszcze tylko zmiany typu Color na Brush

0

Hej, ja jeszcze czegoś takiego nie widziałem to wygląda tak jak byś utworzył sobie kontrolkę a następnie umieszczając ja w w innej kontrolce zmieniasz całkowicie jej tzw. drzewo prezentacji
w tym miejscu:

<ControlTemplate TargetType="{x:Type local:MaterialButton}">
0

@ali663
Nie rozumiem o co Ci chodzi.
Przecież tak się robi ControlTemplate'y.
Tworzy się styl, wskazując na TargetType, w środku Template, i również się wskazuje na TargetType.
https://msdn.microsoft.com/en-us/library/ms753328(v=vs.85).aspx

0

Chodzi mi o to że jak tworzysz własna kontrolkę to w niej określasz jakie jest jej drzewo prezentacji
np :

<UserControl x:Class="test.TestControl"
             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:test"
             mc:Ignorable="d" 
             d:DesignHeight="100" d:DesignWidth="100">
    <Grid >

Tu umieszczam to z czego ma się składać i jak te poszczególne elementy maja się zachowywać np

        <Border Style="{StaticResource MyBorderStyle}"/>
pozostale elementy tej kontrolki

    </Grid>
    </Grid>
</UserControl>

MyBorderStyle wygląda tak np:

    <Style TargetType="{x:Type Border}" x:Key="MyBorderStyle">
        <Setter Property="Background" Value="Yellow"/>
        <Style.Triggers>
            <Trigger Property="Border.IsMouseOver" Value="True">
                <Setter Property="Background" >
                    <Setter.Value>
                        <SolidColorBrush Color="{Binding HoverBrush, RelativeSource={RelativeSource FindAncestor, AncestorType=local:TestControl}}"/>
                    </Setter.Value>
                </Setter>
            </Trigger>
        </Style.Triggers>
    </Style>

teraz jak bede używal tek kontrolki to np tak:

    <local:TestControl HoverBrush="Green"/> <- tu się zmieni na zielona
    <local:TestControl HoverBrush="Red"  Grid.Row="1"/> <- tu border zmieni się na czerwono 

a jak używam nie swoich kontrolek czyli nie mam jej kodu źródłowego i chcę zmienić jej drzewo prezentacji czyli to z czego się składa to wtedy pisze dla niej styl np:

<Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}"> 
Tu umieszczam to z czego ma się składać i jak te poszczególne elementy maja się zachowywać
</ControlTemplate>

1 użytkowników online, w tym zalogowanych: 0, gości: 1