简体   繁体   中英

WPF / MVVM : Need help to fix a broken binding with ContentControl + DataTemplate

I cannot solve a broken binding in my application made in WPF + C# with MVVM pattern.

The message in the output is

"System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.Control', AncestorLevel='1''. BindingExpression:Path=Foreground; DataItem=null; target element is 'Path' (Name=''); target property is 'Fill' (type 'Brush')".

I use a home made component made by a mate who is no more there, this component uses a DataTemplate named "LogDataTemplate".

I made some searches with Google, I found similar cases but I'm not able to fix this broken binding :(

The result of this code works, the circles and triangle are well displayed as expected but there is still this exception in the Output window.

<HomeMadeComponent VerticalAlignment="Bottom"
                   LogListItemTemplate="{StaticResource LogDataTemplate}"
                   StandByBackgroundColor="#FFE6EAEF"
                   PostClickComponentHeight="150"
                   Grid.ColumnSpan="4"/>

<Window.Resources>
     <DataTemplate x:Key="LogDataTemplate">
            <StackPanel Orientation="Horizontal">

                <ContentControl Name="Indicator"
                                Width="8"
                                Height="8"
                                Margin="0,0,5,0"
                                HorizontalAlignment="Center"
                                >
                    <ContentControl.Style>
                        <Style TargetType="{x:Type ContentControl}">
                            <Setter Property="Foreground" Value="Orange" />
                            <Setter Property="Content" Value="{StaticResource CircleBorderOnly}"/>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding sMessageType}" Value="Error">
                                    <Setter Property="Foreground" Value="{StaticResource BaseRed}" />
                                    <Setter Property="Content" Value="{StaticResource Triangle}" />
                                    <Setter Property="LayoutTransform">
                                        <Setter.Value>
                                            <RotateTransform Angle="180"/>
                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding sMessageType}" Value="Warning">
                                    <Setter Property="Foreground" Value="{StaticResource BaseYellow}" />
                                    <Setter Property="Content" Value="{StaticResource Triangle}" />
                                </DataTrigger>
                                <DataTrigger Binding="{Binding sMessageType}" Value="Information">
                                    <Setter Property="Foreground" Value="{StaticResource BaseGreen}" />
                                    <Setter Property="Content" Value="{StaticResource CircleFull}" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ContentControl.Style>
                </ContentControl>

                <TextBlock Text="{Binding sMessage}" Style="{StaticResource DefaultLogTextBlockStyle}" />
            </StackPanel>
        </DataTemplate>
</Window.Resources>

Into a resourceDictionary I have defined my Path

    <Path x:Key="CircleFull"
          x:Shared="False"
          Data="M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"
          Stretch="Fill"
          Fill="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
          />

    <Path x:Key="CircleBorderOnly"
          x:Shared="False"
          Data="M12,20A8,8 0 0,1 4,12A8,8 0 0,1 12,4A8,8 0 0,1 20,12A8,8 0 0,1 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z"
          Stretch="Fill"
          Fill="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
          />

    <Path x:Key="Triangle"
          x:Shared="False"
          Data="M1,21H23L12,2"
          Stretch="Fill"
          Fill="{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
          />

It's my first post on this site, so sorry if the message layout is ugly. Thanks per advance for your help :)

I have found a solution to my problem :)

I wrote a DataTemplate for each shape that I want to display with the DataTrigger (I set it as ContentTemplate), and no more error message in the Output Window :

<Window.Resources>
        <DataTemplate x:Key="LogDataTemplate">
            <StackPanel Orientation="Horizontal">

                <ContentControl Name="Indicator" Width="8" Height="8" Margin="0,0,5,0" HorizontalAlignment="Center"
                                >
                    <ContentControl.Resources>
                        <DataTemplate x:Key="TemplateError">
                            <ContentControl Content="{StaticResource Triangle}" Foreground="{StaticResource BaseRed}"/>
                        </DataTemplate>
                        <DataTemplate x:Key="TemplateWarning">
                            <ContentControl Content="{StaticResource Triangle}" Foreground="{StaticResource BaseYellow}"/>
                        </DataTemplate>
                        <DataTemplate x:Key="TemplateInformation">
                            <ContentControl Content="{StaticResource CircleFull}" Foreground="{StaticResource BaseGreen}"/>
                        </DataTemplate>
                        <DataTemplate x:Key="TemplateDefault">
                            <ContentControl Content="{StaticResource CircleBorderOnly}" Foreground="Gray"/>
                        </DataTemplate>
                        <DataTemplate x:Key="TemplateNull"/>
                    </ContentControl.Resources>

                    <ContentControl.Style>
                        <Style TargetType="{x:Type ContentControl}">
                            <Setter Property="ContentTemplate" Value="{StaticResource TemplateDefault}" />
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding sMessageType}" Value="Error">
                                    <Setter Property="ContentTemplate" Value="{StaticResource TemplateError}" />
                                    <Setter Property="LayoutTransform">
                                        <Setter.Value>
                                            <RotateTransform Angle="180"/>
                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding sMessageType}" Value="Information">
                                    <Setter Property="ContentTemplate" Value="{StaticResource TemplateInformation}" />
                                </DataTrigger>
                                <DataTrigger Binding="{Binding sMessageType}" Value="Warning">
                                    <Setter Property="ContentTemplate" Value="{StaticResource TemplateWarning}" />
                                </DataTrigger>
                                <!-- Used to avoid to display a gray circle when nothing to display -->
                                <DataTrigger Binding="{Binding sMessageType}" Value="{x:Null}">
                                    <Setter Property="ContentTemplate" Value="{StaticResource TemplateNull}" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ContentControl.Style>
                </ContentControl>

                <TextBlock Text="{Binding sMessage}" Style="{StaticResource DefaultLogTextBlockStyle}" />
            </StackPanel>
        </DataTemplate>
</Window.Resources>

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