Laith
Laith

Reputation: 6091

Is there any way I can use value types in x:DataType?

Given this DataTemplate:

<DataTemplate x:DataType="Color">
    ...
</DataTemplate>

I get the following error:

The as operator must be used with a reference type or nullable type ('Color' is a non-nullable value type)

When you follow the error, it takes you to auto-generated code for that view which uses the as operator.

public void DataContextChangedHandler(global::Windows.UI.Xaml.FrameworkElement sender, global::Windows.UI.Xaml.DataContextChangedEventArgs args)
{
        global::Windows.UI.Color data = args.NewValue as global::Windows.UI.Color;
        if (args.NewValue != null && data == null)
        {
        throw new global::System.ArgumentException("Incorrect type passed into template. Based on the x:DataType global::Windows.UI.Color was expected.");
        }
        this.SetDataRoot(data);
        this.Update();
}

I know that {x:Bind} is new, but just in case, does anyone know how to configure it to allow value types, or at least use direct casting?

Upvotes: 9

Views: 3960

Answers (2)

Justin XL
Justin XL

Reputation: 39006

@JeffreyChen's solution is absolutely correct and can be applied to any other value types. But in this particular instance, a reference typed SolidColorBrush which exposes a property of Color is something that the system has already built for you.

I'd suggest to change the Color property in your VM to SolidColorBrush because the only time you would need a Color in your xaml is when you want smooth ColorAnimation between two states. If this is the case you do -

<ListView ItemsSource="{x:Bind Vm.Brushes}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="SolidColorBrush">
            <TextBlock Text="Test">
                <TextBlock.Foreground>
                    <SolidColorBrush Color="{x:Bind Color}" />
                </TextBlock.Foreground>
            </TextBlock>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Otherwise, you simply bind to XAML control's Foreground/Background/BorderBrush which is already a type of Brush.

<ListView ItemsSource="{x:Bind Vm.Brushes}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="SolidColorBrush">
            <TextBlock Text="Test" Foreground="{x:Bind}" />
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

Upvotes: 2

Jeffrey Chen
Jeffrey Chen

Reputation: 4690

I have the same issue when binding the Windows Runtime Type like “Windows.UI.Color” in x:DateType.

The current workaround I used is wrapping a .NET Reference Type.

public class BindModel
{
    public Windows.UI.Color Color { get; set; }
}

<DataTemplate x:Key="test" x:DataType="local:BindModel">
    <TextBlock>
        <TextBlock.Foreground>
            <SolidColorBrush Color="{x:Bind Color}"></SolidColorBrush>
        </TextBlock.Foreground>
    </TextBlock>
</DataTemplate>

Upvotes: 5

Related Questions