ValueWhenConverter and Enum - template10

How can I use the ValueWhenConverter with a enum?
For example:
<Grid Visibility="{x:Bind ViewModel.ViewModelStatus, Mode=OneWay, Converter={StaticResource ViewStatusConverter}}">
..
</Grid>
<converters:ValueWhenConverter x:Key="ViewStatusConverter">
<converters:ValueWhenConverter.When>
<vm:ViewModelStates>Error</vm:ViewModelStates>
</converters:ValueWhenConverter.When>
<converters:ValueWhenConverter.Value>
<Visibility>Visible</Visibility>
</converters:ValueWhenConverter.Value>
<converters:ValueWhenConverter.Otherwise>
<Visibility>Collapsed</Visibility>
</converters:ValueWhenConverter.Otherwise>
</converters:ValueWhenConverter>
I don't think this syntax is correct: <vm:ViewModelStates>Error</vm:ViewModelStates>
How do I map the ValueWhenConverter to my enum values?

Unfortunately WhenValueConverter cant be map to enums, I tried using this:
<converter:ValueWhenConverter x:Key="EnumSexToBooleanConverter">
<converter:ValueWhenConverter.When>
<vm:RegisterPageViewModel>
<vm:RegisterPageViewModel.PersonalInfo>
<model:Personal>
<model:Personal.Sex>
0
</model:Personal.Sex>
</model:Personal>
</vm:RegisterPageViewModel.PersonalInfo>
</vm:RegisterPageViewModel>
</converter:ValueWhenConverter.When>
<converter:ValueWhenConverter.Value>
<ToggleSwitch>
<ToggleSwitch.IsOn>
<x:Boolean>True</x:Boolean>
</ToggleSwitch.IsOn>
</ToggleSwitch>
</converter:ValueWhenConverter.Value>
<converter:ValueWhenConverter.Otherwise>
<ToggleSwitch>
<ToggleSwitch.IsOn>
<x:Boolean>False</x:Boolean>
</ToggleSwitch.IsOn>
</ToggleSwitch>
</converter:ValueWhenConverter.Otherwise>
</converter:ValueWhenConverter>
and it throws an InvalidCast exception, it is a good converter when using value types, such as x:Boolean, x:Int32, x:Double and x:String, also it has some enum values integrated in the xaml like visibility property which uses enums such as Visible and Collapsed.
as far as I try right now, and I even tried many different way, there is no way to use a WhenValueConverter with an enum.
If you need to make a conversion from a boolean to an enum and viceversa i suggest to create your own converter using IValueConverter.
That would be your best choice for your actual Issue.
Also if you wish to be able to map WhenValueConverter to your enum values it can be achieved by changing your viewmodel property to a dependency property like this:
public Gender Sex
{
get { return (Gender)GetValue(SexProperty); }
set { SetValue(SexProperty, value); }
}
public static readonly DependencyProperty SexProperty =
DependencyProperty.Register(
nameof(Sex), typeof(Gender),
typeof([YourContainerType]),
new PropertyMetadata([initial_default_or_null_here])
);
}
public enum Gender : int
{
Female,
Male
}
this is only an example and the author of this sample dg2k from the Template 10 github project.
Template 10 - WhenValueConverter to Enum Values

Related

What's the access level of a case within a private enumeration

I read the document about Swift 5.1 from swift.org and have some questions about access level in enumeration.
https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html#ID14
In the document, it says:
The individual cases of an enumeration automatically receive the same access level as the enumeration they belong to.
private enum SomePrivateEnum {
case one
case two
case three
}
private class SomePrivateClass {
private var somePrivateProperty = 0
}
// work
print(SomePrivateEnum.one)
// error: 'somePrivateProperty' is inaccessible due to 'private' protection level
print(SomePrivateClass().somePrivateProperty)
According to the document, if I have a private enum, then all cases should receive private access level. The question is, why can I access the private case outside the enum declaration ? This behavior is different from Class.
First of all, your code is completely artificial, as it would not even compile except in a playground — and in a playground the concepts of privacy are more or less meaningless. Test only within a real project.
When you do, you will have something like this:
private enum SomePrivateEnum {
case one
case two
case three
}
private class SomePrivateClass {
private var somePrivateProperty = 0
}
class ViewController : UIViewController {
func test() {
print(SomePrivateEnum.one)
print(SomePrivateClass().somePrivateProperty)
}
}
Now that we've established that, we can proceed to what's wrong with your test itself, namely that you are comparing apples with oranges. Here's the parallelism:
print(SomePrivateEnum.one) // ok
print(SomePrivateClass()) // ok
So private for SomePrivateEnum and private for SomePrivateClass mean the same thing, namely: "private within this file". This code is in the same file so it can see both SomePrivateEnum and SomePrivateClass. (As the docs tell you, code that can see SomePrivateEnum can see SomePrivateEnum.one, and vice versa. So we are now comparing apples with apples.)
But private for somePrivateProperty means something else. It means "private within this type". So only code inside SomePrivateClass can see somePrivateProperty. This code is not inside SomePrivateClass, so it can't see that property.
You can access private declarations inside current context.
for example, if you wrap enum with other context - it will not be accessible same way as property inside SomePrivateClass.
i.e. this will be inaccessible:
struct Foo {
private enum SomePrivateEnum {
case one
case two
case three
}
}
print(Foo.SomePrivateEnum.one)
and this will be:
private class SomePrivateClass {
var somePrivateProperty = 0
}
print(SomePrivateClass().somePrivateProperty)

C++11: How to create an enum class inside an class that behaves like a sub class?

To explain my problem I posted an example below. The code in this form is not tested so there might be some syntax mistake in it. As I have to work with a lot of registers in an integrated circuit with their addresses which can be remapped, it would be very useful to create structures like that below. Is there some trick to create these structures? As this example does not work the way I want it because foo requires a Country object and Country::Europe::Italy is invalid as parameter.
// I want to create a structure like this
class myClass {
public:
class Country {
enum class Europe {
England,
France,
Germany,
Italy
};
enum class Asia {
China,
Japan
};
};
// Here I want to make sure, that the method is only
// called with a Country element and e.g. Italy should
// behave like a Country object. Actually it should behave
// as if it is derived from Country.
int foo(Country c);
};
int main() {
myClass myC();
// Exemplary call of the method foo
myC.foo(myClass::Country::Europe::Italy);
}
You cannot use enum class to achieve your goal. However, you can use a namespace with a set of hardcoded constexpr objects:
struct Country
{
int _id;
};
namespace Countries
{
namespace Europe
{
constexpr Country Italy{0};
constexpr Country France{1};
};
};
Usage:
myC.foo(Countries::Europe::Italy);
A proper example using registers and a better explanation would have been better. I guess you want to remap from one register name to another. A suggestion:
class Register {
public:
enum class UserName {
REG_IO0,
REG_MEM1
};
enum class CPUName {
REG_INT0,
REG_INT1
};
void setMapping(UserName from, CPUName to); // store the mapping
CPUName getMapping(UserName name) const; // retrieve the mapping
private:
std::map<UserName, CPUName> m_registerMap;
};
If you want you could implement get/set methods for the registers in that class if you store the indexes/adresses of the registers. Either use templates or overload them for different data types.
You can explicitly use an enum type as a function or constructor argument, restricting the caller to using that enumeration.
The thing you can't trivially do is combine multiple enum definitions in the way that you have suggested.
You could write several constructors, one for each of the enums Europe, Asia, etc, but that would be work, especially if you have a number of functions that need to take these enums as arguments.
--OR--
You could define one big enum, and define fixed value separators for each subgroup, so you can compare the enum value against these guard values to identify the subgroup. You lose the sub-grouping if you do that. You could use c++11 constant enum initialisers to construct enum value members in subclasses for each continent - but note these are only available for enum class from c++17 (so I am using a nested class trick to provide the member namespace enforcement - in c++17 you could have enum class Location - you can write this in c++11 but you can't then do the const initialisers). The values follow the above rule of separators, but callers have to indirect through the subclasses to get the names.
class Country
{
class Location {
enum Value {
None =0,
Europe = 0x0100,
Asia = 0x0200,
//etc
};
};
struct Asia {
const Location::Value Japan { Location::Asia + 1 };
//etc
};
struct Europe {
const Location::Value UnitedKingdom { Location::Europe + 1 };
//etc
};
// etc
};
Then you could have
class myClass {
public:
myClass(Country::Location::Value v);
};
And call it with
myClass instance(Country::Asia::Japan);
-- OR --
You could define another structure who's only purpose is to take the various enumerations and convert them to a pair of values for the continent and country index. You could then use that structure as your function parameter, and allow auto-conversion from that structure. This means you only do the conversion once, and callers to your code are not impacted. You could use the guard ranges such that you don't need to explicitly store the continent code, just the raw country number would be unique across all your enums.

Unity3D & YamlDotNet Deserializing Data into Monobehaviour-derived classes

I'm trying to serialize data into / from my classes, derived from MonoBehaviour, which cannot be created from client code (e.g., with the new keyword), but rather must be created by a Unity3D-specific method, GameObject.AddComponent<T>(). How can I use the YamlDotNet framework to populate my classes with values without having to create an adapter for each one? Is there some sort of built-in adapter that I can configure, such that YamlDotNet doesn't instantiate the class it's trying to serialize to?
A typical file might contain a mapping of items, e.g.,
%YAML 1.1
%TAG !invt! _PathwaysEngine.Inventory.
%TAG !intf! _PathwaysEngine.Adventure.
---
Backpack_01: !invt!Item+yml
mass: 2
desc:
nouns: /^bag|(back)?pack|sack|container$/
description: |
Your backpack is only slightly worn, and...
rand_descriptions:
- "It's flaps twirl in the breeze."
- "You stare at it. You feel enriched."
MagLite_LR05: !invt!Lamp+yml
cost: 56
mass: 2
time: 5760
desc:
nouns: /^light|flashlight|maglite|lr_05$/
description: |
On the side of this flashlight is a label...
(Type "light" to turn it on and off.)
...
Where the tags are the fully specified class names of my Items, e.g., PathwaysEngine.Inventory.Lamp+yml, PathwaysEngine is the namespace I use for my game engine code, Inventory deals with items & whatnot, and Lamp+yml is how the compiler denotes a nested class, yml inside Lamp. Lamp+yml might look like this:
public partial class Lamp : Item, IWearable {
public new class yml : Item.yml {
public float time {get;set;}
public void Deserialize(Lamp o) {
base.Deserialize((Item) o);
o.time = time;
}
}
}
I call Deserialize() on all objects that derive from Thing from Awake(), i.e., once the MonoBehaviour classes exist in the game. Elsewhere, I've already created a pretty complicated Dictionary filled with objects of type Someclass+yml, and then Deserialize takes an instance of the real, runtime class Someclass and populates it with values. There's got to be a cleaner way to do this, right?
How can I:
Tell the Deserializer what my classes are?
See the second edit for a good solution for the above issue
Get the data without it attempting to create my MonoBehaviour-derived classes?
Edit: I've since worked at the problem, and have found out a good way of dealing with custom data (in my particular case of trying to parse regexes out of my data, and having them not be considered strings & therefore, un-castable to regex) is to use a IYamlTypeConverter for that particular string. Using YamlDotNet with Unity3D MonoBehaviours, however, is still an issue.
Another Edit: The above examples use a pretty ugly way of determining types. In my case, the best thing to do was to register the tags first with the deserializer, e.g.,
var pre = "tag:yaml.org,2002:";
var tags = new Dictionary<string,Type> {
{ "regex", typeof(Regex) },
{ "date", typeof(DateTime) },
{ "item", typeof(Item) }};
foreach (var tag in tags)
deserializer.RegisterTagMapping(
pre+tag.Key, tag.Value);
Then, I use the !!tag notation in the *.yml file, e.g.,
%YAML 1.1
---
Special Item: !!item
nouns: /thing|item|object/
someBoolean: true
Start Date: !!date 2015-12-17
some regex: !!regex /matches\s+whatever/
...
You can pass a custom implementation of IObjectFactory to the constructor of the Deserializer class. Every time the deserializer needs to create an instance of an object, it will use the IObjectFactory to create it.
Notice that your factory will be responsible for creating instances of every type that is deserialized. The easiest way to implement it is to create a decorator around DefaultObjectFactory, such as:
class UnityObjectFactory : IObjectFactory
{
private readonly DefaultObjectFactory DefaultFactory =
new DefaultObjectFactory();
public object Create(Type type)
{
// You can use specific types manually
if (type == typeof(MyCustomType))
{
return GameObject.AddComponent<MyCustomType>();
}
// Or use a marker interface
else if (typeof(IMyMarkerInterface).IsAssignableFrom(type))
{
return typeof(GameObject)
.GetMethod("AddComponent")
.MakeGenericMethod(type)
.Invoke();
}
// Delegate unknown types to the default factory
else
{
return DefaultFactory(type);
}
}
}

method based on variable type

I just have the following scenario
i want to return string from method but the method should be based on variable type which is (Type CType)
i need to make the render class like this
public string render(TextBox ctype){
return "its text box";
}
public string render(DropDown ctype){
return "its drop down";
}
you know TextBox is a Type thats why i can declare the Type variable like this
var CType = typeof(TextBox)
and i need to call the render method like this
render(Ctype);
so if the Ctype is type of TextBox it should call the render(TextBox ctype)
and so on
How can i make it ?
you should use a template function
public customRender<T>(T ctype)
{
if(ctype is TextBox){
//render textbox
}
else if(ctype is DropDown){
//render dropdown
}
}
hope it will help
First of all, even if you don't see an if or a switch, there will still be one somewhere hidden inside some functions. Distinguishing types at runtime that are not known at compile-time simply will not be possible without any such kind of branching of the control flow.
You can use one of the collection classes to build a map at runtime that maps Type instances to Func<T, TResult> methods. For example, you can use the Dictionary type to create such a map:
var rendererFuncs = new Dictionary<Type, Func<object, string>>();
You could then add some entries to that dictionary like this:
rendererFuncs[typeof(TextBox)] = ctype => "its text box";
rendererFuncs[typeof(DropDown)] = ctype => "its drop down";
Later on, you can call the appropriate function like this:
string renderedValue = rendererFuncs[Ctype.GetType()](Ctype);
Or, if you want to be on the safe side (in case there are Ctype values that have no appropriate renderer):
string renderedValue;
Func<object, string> renderer;
if (rendererFuncs.TryGetValue(Ctype.GetType(), out renderer)) {
renderedValue = renderer(Ctype);
} else {
renderedValue = "(no renderer found)";
}
Note that this will only work for as long as Ctype is of the exact type used as a key in the dictionary; if you want any subtypes to be correctly recognized as well, drop the dictionary and build your own map that traverses the inheritance hierarchy of the type being searched (by using the Type.BaseType property).

How should the enum type look like in the bottom part of a UML diagram?

I know what the enum type should look like in the middle section of a UML diagram but how should it look in the bottom section where it contains the actions/methods of the class? Isn't there accessors and mutators for enum types?
+GetTypeOfAttack:TypeOfAttack
Is probably the answer but you need to ask yourself a question about whether this is a 'classic' accessor mutator
A classic accessor/mutator (getter/setter) is usually like the following
private bool hiddenField = true;
//Accessor
public bool GetHiddenField()
{
return hiddenField;
}
//mutator
public void SetHiddenField(bool input)
{
hiddenField = input;
}
BUT you may (more often than not) have situations where you need to do some logic evaluation before either getting or setting the field... This is not a pure accessor/mutator but essentially it is.
In answer to your question:
+SetHiddenField(bool): void
+GetHiddenField:bool
See how they map to the previous code. +/- = public/private, (denoteParameters) and : denotes return type