How can I bind to a null value inside a template i

2019-06-17 09:07发布

问题:


Before you answer, look at this post.

Getting an answer for that first may resolve the issue below.


This is a problem that just started with Windows 10 (Universal Apps). In Windows 8.1, and every other XAML technology, this technique worked flawlessly. Here's the setup in a blank universal app project:

1. Static class with Attached Property

Create a class that houses an attached property of type Brush. Put this anywhere in the project.

public static class MySettings
{
    public static Brush GetAccentBrush(DependencyObject d)
    {
        return (Brush)d.GetValue(AccentBrushProperty);
    }

    public static void SetAccentBrush(DependencyObject d, Brush value)
    {
        d.SetValue(AccentBrushProperty, value);
    }

    public static readonly DependencyProperty AccentBrushProperty = DependencyProperty.RegisterAttached(
        "AccentBrush",
        typeof(Brush),
        typeof(MySettings),
        null
        );
}

2. Add a control to your MainPage.xaml using attached property

In the main page, add a ContentControl with a custom template that has a Grid with its background color set to the accent brush. The accent brush is set in a style.

<Page x:Class="UniversalTest.MainPage"
      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="using:UniversalTest"
      mc:Ignorable="d">
    <Page.Resources>
        <Style x:Key="MyControl"
               TargetType="ContentControl">
            <Setter Property="local:MySettings.AccentBrush"
                    Value="Green" /> <!-- Setting value here -->
        </Style>
    </Page.Resources>

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

        <ContentControl Style="{StaticResource MyControl}">
            <ContentControl.Template>
                <ControlTemplate TargetType="ContentControl">
                    <Grid Background="{TemplateBinding local:MySettings.AccentBrush}"> <!-- Using value here -->
                        <TextBlock Text="Howdy World!" />
                    </Grid>
                </ControlTemplate>
            </ContentControl.Template>
        </ContentControl>

    </Grid>
</Page>

If you run the app now, it will show up with a green background. Everything works. However, if you set the value as {x:Null}, it throws an exception.

<Page.Resources>
    <Style x:Key="MyControl"
            TargetType="ContentControl">
        <Setter Property="local:MySettings.AccentBrush"
                Value="{x:Null}" /> <!-- Null value here -->
    </Style>
</Page.Resources>

Would anyone like to take a shot at this?

回答1:

For the record, this issue appears to have been fixed. My project references Universal Windows version 10.0.10240.0. Setting the brush to {x:Null} as described by the original poster works as expected.



回答2:

You can add a fake attached property :

    public static Brush GetNullAccentBrush(DependencyObject d)
    {
        return (Brush)d.GetValue(NullAccentBrushProperty);
    }

    public static void SetNullAccentBrush(DependencyObject d, Brush value)
    {
        d.SetValue(NullAccentBrushProperty, value);
    }

    public static readonly DependencyProperty NullAccentBrushProperty = DependencyProperty.RegisterAttached(
        "NullAccentBrush",
        typeof(SolidColorBrush),
        typeof(MySettings),
        null
        );

And bind your property setter :

<Setter Property="local:MySettings.AccentBrush"
        Value="{Binding local:MySettings.NullAccentBrush}" />

The grid Background is null (even if there is no real binding on NullAccentBrush...).



回答3:

I've found that this code works, in resource file

<Color x:Key="BgNull"></Color>

then in your style use that link to BgNull

<Setter Property="Background" Value="{StaticResource BgNull}"/>