Is it possible to create a generic converter between enum values and ints? I have a set of similar converters in my project:
Object^ SpecificEnumIntConverter::Convert(Object^ value, TypeName targetType, Object^ parameter, String^ language)
{
const auto asEnum = static_cast<SpecificEnumType>(value);
const auto asInt = static_cast<int>(asEnum);
return asInt;
}
Object^ SpecificEnumIntConverter::ConvertBack(Object^ value, TypeName targetType, Object^ parameter, String^ language)
{
const auto asInt = static_cast<int>(value);
const auto asEnum = static_cast<SpecificEnumType>(asInt);
return asEnum;
}
These converters are usually used to binding with ViewModel, i.e:
<ListBox SelectedIndex="{x:Bind VM.EnumTypeProperty, Mode=TwoWay, Converter={StaticResource SpecificEnumIntConverter}}">
I am wondering if it is possible to implement a generic converter.
Thanks in advance and best regards!
It is possible to define generic converter by using template<...> somehow.
public enum class EnumType1 : int
{
Foo1, Bar1
};
public enum class EnumType2 : int
{
Foo2, Bar2
};
// C++/CLI's syntax "generic<...> public ref class ... " cannot be used in C++/CX.
template <class _T>
ref class GenericEnumConverter : Windows::UI::Xaml::Data::IValueConverter
{
public:
virtual Platform::Object ^ Convert(Platform::Object ^value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object ^parameter, Platform::String ^language)
{
const auto asEnum = static_cast<_T>(value);
const auto asInt = static_cast<int>(asEnum);
return asInt;
}
virtual Platform::Object ^ ConvertBack(Platform::Object ^value, Windows::UI::Xaml::Interop::TypeName targetType, Platform::Object ^parameter, Platform::String ^language)
{
const auto asInt = static_cast<int>(value);
const auto asEnum = static_cast<_T>(asInt);
return asEnum;
}
};
However it's not possible to lay such converters directly in Resources via XAML (because templated-class in C++/CX cannot take "public" accessibility-modifier). So you need to deploy them in code behind.
[Windows::Foundation::Metadata::WebHostHidden]
public ref class MainPage sealed
{
public:
MainPage()
{
Resources->Insert(L"EnumType1Converter", ref new GenericEnumConverter<EnumType1>());
Resources->Insert(L"EnumType2Converter", ref new GenericEnumConverter<EnumType2>());
InitializeComponent();
}
property EnumType1 Value1 {
EnumType1 get() { return m_Value1; }
void set(EnumType1 value) {
m_Value1 = value;
//OutputDebugString((m_Value1.ToString() + L"\r")->Begin());
}
}
property EnumType2 Value2 {
EnumType2 get() { return m_Value2; }
void set(EnumType2 value) {
m_Value2 = value;
//OutputDebugString((m_Value2.ToString() + L"\r")->Begin());
}
}
private:
EnumType1 m_Value1 = EnumType1::Foo1;
EnumType2 m_Value2 = EnumType2::Bar2;
};
Then you can use the converters in binding.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<ListBox SelectedIndex="{x:Bind Value1, Converter={StaticResource EnumType1Converter}, Mode=TwoWay}" Margin="16">
<ListBoxItem>Foo1</ListBoxItem>
<ListBoxItem>Bar1</ListBoxItem>
</ListBox>
<ListBox SelectedIndex="{x:Bind Value2, Converter={StaticResource EnumType2Converter}, Mode=TwoWay}" Margin="16">
<ListBoxItem>Foo2</ListBoxItem>
<ListBoxItem>Bar2</ListBoxItem>
</ListBox>
</StackPanel>
</Grid>