Skip to content

WPF MVVM Sample App #353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 7, 2018
Merged

WPF MVVM Sample App #353

merged 8 commits into from
Jan 7, 2018

Conversation

dayewah
Copy link
Contributor

@dayewah dayewah commented Jan 1, 2018

Here's a simple sample app that I think would have been useful to me when I first came across this excellent library. Not sure how many people are doing UI apps with this but I thought I would share my strategy as a sample. Let me know if any thing is amiss. Hope it is found to be a useful addition to the library. Btw this is my first pull request on github. Hoping its all done right and I promise I won't be offended if it is rejected :)

Thanks

Copy link
Owner

@angularsen angularsen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks great, just a couple of minor things you could look at.

It's awesome you took the time to prepare a sample to share with others. I think we should be able to reduce the amount of reflection code, maybe with some tweaks in the library, but this is more of a potential improvement and does not in anyway block merging in this PR.

I'd still like to get some input from the other collaborators before merging this in.


It performs a simple calculation allowing flexibility in the units for parameters and results. Default units for each are specified in the settings drop down.

A key feature enabling this sample is the UnitToStringConverter class
Copy link
Owner

@angularsen angularsen Jan 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add link to the file

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.

@@ -0,0 +1,13 @@
## WPF MVVM Sample
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This readme is great!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool

//if (actualEnumType == this._enumType)
// return enumValues;

//ommits the first enum element, typically "undefined"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo

Type actualEnumType = Nullable.GetUnderlyingType(this._enumType) ?? this._enumType;
Array enumValues = Enum.GetValues(actualEnumType);

//if (actualEnumType == this._enumType)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider removing commented out code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do.


//ommits the first enum element, typically "undefined"
Array tempArray = Array.CreateInstance(actualEnumType, enumValues.Length -1);
Array.ConstrainedCopy(enumValues,1,tempArray, 0,enumValues.Length-1);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably a stupid question as I don't fully understand this, but can't you just return enumValues.Skip(1).ToArray() here if the idea is to exclude the first/default enum value?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great tip. Thought I was stuck with the old array methods. Just needed a simple cast() to simplify things.


var result = unitType
.GetMethod("ToString", new[] { unitEnumType, typeof(IFormatProvider), typeof(int) })
.Invoke(value, new object[] { unitEnumValue, null, significantDigits });
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My only concern is that this is quite heavy on reflection and might easily break at runtime when subtle changes to the library are made that are backwards compatible on calling code, but incompatible with the reflection method signatures expected here.

I think maybe the library could be adapted a bit to facilitate this better. I have only given this a brief thinking, but I I think it would help to make https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/CustomCode/QuantityParser.cs public in order to give access to the quantity value+unit parsing without having to use all the reflection bits?
I would need to spend more time evaluating this, but I think we should be able to simplify this type of integration to avoid so much reflection code. For now just consider this a rambling comment as I don't have a clear vision for how to best achieve that yet.

@JKSnd @eriove @ferittuncer I'm seeing some potential usecases for exposing BaseUnit and ToString overloads in an interface or base class for quantities here, as discussed earlier.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the reflection is a bit clunky. Any library enhancements that better enable this strategy would be welcome.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, we have experienced these problems too when we used this library in our GUI. Lacking base classes for units and quantities forces implementation to reflection as presenter layer doesn't know which unit or quantity it's dealing with at the runtime.

Perhaps there are other ways we couldn't see, I'm not sure. I just have an instinct that we should have base classes. You know better, your call @angularsen

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A common interface for all quantities would be a simple addition (at least if it contained members that are already there) and wouldn't incur any performance hit (boxing) as long as it isn't used.

That's of course not part of this pull request but it is much easier to see in this context.

@dayewah
Copy link
Contributor Author

dayewah commented Jan 3, 2018

Updates complete

@angularsen
Copy link
Owner

Alright, so I think we agree this is ready to merge and that there is some possibility to improve this sample by looking for ways for the library to provide the information that is now gathered by the reflection code.

@angularsen angularsen merged commit 5df0b5f into angularsen:master Jan 7, 2018
@angularsen
Copy link
Owner

Thanks @dayewah !

@angularsen
Copy link
Owner

I won't personally pursue the case of improving the reflection code as discussed above, but at least this gives us a concrete usecase to refer to in future discussion. If someone wants to draft up a proposal on how to avoid reflection code in this sample and similar usecases, just create an issue for it and I would be happy to participate in the discussion and bring that into the library.

@dayewah
Copy link
Contributor Author

dayewah commented Jan 9, 2018

Great! Thanks @angularsen. I'll continue to monitor progress with library changes and perhaps make suggestions if I come up with anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants