x:Static in UWP XAML
Asked Answered
T

5

31

An app I'm working on requires a ConverterParameter to be an enum. For this, the regular way to do would be:

{Binding whatever, 
    Converter={StaticResource converterName}, 
    ConverterParameter={x:Static namespace:Enum.Value}}

However, the UWP platform x: namespace does not seem to have the Static extension.

Does anyone know if there's a solution that does not rely on x:Static for comparing an enum in binding?

Telophase answered 12/8, 2015 at 11:28 Comment(2)
I haven't done any UWP, so I don't know, but there's this article explaining how to make a markup extension for Silverlight (which doesn't have x:Static either). It may apply hereGirth
Here's answer about using enum in xaml that must workWhitmire
B
48

This works for me in a UWP:

<Button Command="{Binding CheckWeatherCommand}">
  <Button.CommandParameter>
     <local:WeatherEnum>Cold</local:WeatherEnum>
  <Button.CommandParameter>
</Button>
Basilica answered 23/2, 2016 at 22:16 Comment(4)
Wow, this needs to be upvoted more. That works perfectly, no workarounds needed with classes and what not.Fivefold
Is there any way to specify this in line via CommandParameter=..., to avoid the xaml in the button body?Monmouth
@Monmouth Seems to work fine declaring the type as a resource. <local:WeatherEnum x:Key="Cold">Cold</local:WeatherEnum> then referenced anywhere CommandParameter={StaticResource Cold}. Not as clean as x:Static and inline but it saves adding the XAML wrappers everytime.Wingate
I'm getting unable to cast .... to object of type .... error tooltip in XAML. And in runtime the value is null.Multilingual
K
11

The most concise way I know of...

public enum WeatherEnum
{
    Cold,
    Hot
}

Define the enum value in XAML:

<local:WeatherEnum x:Key="WeatherEnumValueCold">Cold</local:WeatherEnum>

And simply use it:

"{Binding whatever, Converter={StaticResource converterName},
 ConverterParameter={StaticResource WeatherEnumValueCold}}"
Kernel answered 8/12, 2015 at 12:51 Comment(2)
That doesn't work for me... I tried as you suggested, but on runtime I get this error: The TypeConverter for "Phase" does not support converting from a string. (Phase is my enumerator)Selfcentered
This doesn't work me either. It throws a conversion errorHypaethral
S
10

There is no Static Markup Extension on UWP (and WinRT platform too).

One of the possible solutions is to create class with enum values as properties and store instance of this class in the ResourceDictionary.

Example:

public enum Weather
{
    Cold,
    Hot
}

Here is our class with enum values:

public class WeatherEnumValues
{
    public static Weather Cold
    {
        get
        {
            return Weather.Cold;
        }
    }

    public static Weather Hot
    {
        get
        {
            return Weather.Hot;
        }
    }
}

In your ResourceDictionary:

<local:WeatherEnumValues x:Key="WeatherEnumValues" />

And here we are:

"{Binding whatever, Converter={StaticResource converterName},
 ConverterParameter={Binding Hot, Source={StaticResource WeatherEnumValues}}}" />
Savoury answered 13/9, 2015 at 20:2 Comment(0)
G
1

This is an answer utilizing resources and without Converters:

View:

<Page
.....
xmlns:local="using:EnumNamespace"
.....
>
  <Grid>
    <Grid.Resources>
        <local:EnumType x:Key="EnumNamedConstantKey">EnumNamedConstant</local:SettingsCats>
    </Grid.Resources>

    <Button Content="DoSomething" Command="{Binding DoSomethingCommand}" CommandParameter="{StaticResource EnumNamedConstantKey}" />
  </Grid>
</Page>

ViewModel

    public RelayCommand<EnumType> DoSomethingCommand { get; }

    public SomeViewModel()
    {
        DoSomethingCommand = new RelayCommand<EnumType>(DoSomethingCommandAction);
    }

    private void DoSomethingCommandAction(EnumType _enumNameConstant)
    {
     // Logic
     .........................
    }
Grivet answered 16/6, 2017 at 20:47 Comment(1)
Doesn't seem to work in WinUi3 for me.Semivowel
A
1

In most situations, x:Bind is a drop-in replacement for x:Static, so you can do:

ConverterParameter="{x:Bind namespace:Enum.Value}}"

If you need x:Bind in a resource dictionary, you will need to give it a code-behind file: https://learn.microsoft.com/en-us/windows/uwp/data-binding/data-binding-in-depth#resource-dictionaries-with-xbind

Ambulance answered 9/8, 2023 at 10:10 Comment(19)
Doesn't work if nexted in another {x:Bind}Semivowel
@Semivowel If you are using x:Bind you dont need a converter, you can use a method binding with multiple parameters.Ambulance
I'm trying to bind a radio button IsChecked property, I'm not sure how that could be done with a method binding.Semivowel
@Semivowel Trying to bind it to what?Ambulance
@Semivowel Did you look at this? learn.microsoft.com/en-us/windows/uwp/data-binding/…Ambulance
I'm binding IsChecked from multiple radio buttons to a string property and using the converter parameter to identify which radio button should be checked. I wanted to switch from string to enum but could not find a way to send the enum as a converter parameter. {x:Bind} to function can be used for getting the value but BindBack does not allow sending extra parameters so there's no way to know from which radio button the boolean value is coming from.Semivowel
Only solution I found currently is to create a separate BindBack method per radio button which works but is not really that clean as you now have multiple SomethingChecked methods in the view model which do very similar things and need to return a bool.Semivowel
@Semivowel Have you tried using the RadioButtons control, which supports binding to an items source and a selected item?Ambulance
@Semivowel learn.microsoft.com/en-us/windows/winui/api/…Ambulance
This seems like a better option, thanks!Semivowel
x:Bind only works in code-behind situations - at least in the newest WinUI - so it's really not a "drop-in replacement"Haycock
@EmperorEto Not sure what you mean.Ambulance
If you do an x:Bind in a XAML file that's not the code-behind of a Window or a UserControl - like a ResourceDictionary - it throws a compile error. XamlCompiler error WMC1119: This Xaml file must have a code-behind class to use {x:Bind}. See http://go.microsoft.com/fwlink/?LinkID=532920&clcid=0x409 for more informationHaycock
You can give your resource dictionary a code-behind file.Ambulance
@EmperorEto See here: learn.microsoft.com/en-us/windows/uwp/data-binding/…Ambulance
But yes, point taken, in some cases it's not just simple "drop-in". Updated answer.Ambulance
Well whadaya know! I had no idea. Thanks much.Haycock
RHGGHG. WinUI 3 SDK 1.5 - x:Bind requires the root element of your page to inherit from FrameworkElement or Window, but root type 'Microsoft.UI.Xaml.ResourceDictionary' does notHaycock
Let us continue this discussion in chat.Ambulance

© 2022 - 2024 — McMap. All rights reserved.