Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 365
Laith Avatar asked Oct 01 '15 05:10

Laith


2 Answers

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>
like image 98
Jeffrey Chen Avatar answered Oct 21 '22 05:10

Jeffrey Chen


@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>
like image 27
Justin XL Avatar answered Oct 21 '22 05:10

Justin XL