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
Pull Request: Adding New Control NumericUpDown Control to Material Design XAML Toolkit #3175
base: master
Are you sure you want to change the base?
Pull Request: Adding New Control NumericUpDown Control to Material Design XAML Toolkit #3175
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One other thing that would be good to do is write some UI tests for this control. If you need any help setting that up, let me know.
<smtx:XamlDisplay Margin="10,5" | ||
VerticalAlignment="Top" | ||
UniqueKey="numericUpDown_default"> | ||
<materialDesign:NumericUpDown /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to put in a few more examples showing the commands, Min and Max, and any other styles.
MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.NumericUpDown.xaml
Outdated
Show resolved
Hide resolved
MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.NumericUpDown.xaml
Outdated
Show resolved
Hide resolved
Padding="8,4" | ||
Command="{TemplateBinding DecreaseCommand}"/> | ||
|
||
<TextBox x:Name="PART_TextBoxField" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We probably also want to forward the TextBox hint properties. These are attached properties that should be forwarded into the TextBox so that consumers can change them.
https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/master/MainDemo.Wpf/Fields.xaml#L107-L118
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a reply to one of your comments @Keboo.
UPDATE:
While working on the TimePicker
style, I think I have managed to leverage the existing TextBox
styles. So for controls like these that "look" like a TextBox
, we simply hijack one of the padding parameters to be able to add content on top of the TextBox
but giving the appearance that the content is inside the TextBox
. Of course this only really works when content is added on the far right/left but that is often the case. So for this particular control, we could leverage the TextBox
style, but make the right padding big enough to fit in the plus/minus buttons. That way we get all the TextBox
goodness out of the box, and simply need to add the sugar on top (the extra buttons).
My original comment:
I think, similar to some of the other controls that "host" a TextBox
, we probably want to strip that particular TextBox
of all the fancy MDIX stuff and implement it directly in the template for the NumericUpDown
.
In other words, I assume this should eventually include all the prefix-/suffix-texts, leading-/trailing-icons, SmartHint
, etc. If you look at some of the other controls (ComboBox
for example), you will see that those things are handled in the "host" template, and not leveraging a "styled" TextBox
.
To elaborate on the above. Today we cannot easily leverage a "styled" Textbox
with the way our triggers are working today I believe, and therefore we end up having to duplicate a lot of the stuff (you'll see that in the other control styles). It may be a future refactoring task to see if we can somehow leverage a "styled" TextBox
in the controls that nests one of those rather than having to handle all the fancy stuff in the "host" template.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect, I will see about getting that change done.
Any update on this? @Asivaprasadam? Would be cool to have this in my project, this is exactly what I need! |
@tim-gromeyer I have changed my work abit and switched from UI development to more of a backend development. But I'll check with the progress and do an update possibly asap, but lets say optimally by end of Jan worst case by march. Feel free to take over too! |
- Auto generated control template added. - Auto generated style from Generic.xaml moved to the specific style file (MaterialDesignTheme.NumericUpDown.xaml).
Adding UI tests
799b4e4
to
dfe8f13
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few comments to consider.
@@ -16,7 +17,7 @@ namespace MaterialDesignThemes.UITests; | |||
|
|||
public abstract class TestBase(ITestOutputHelper output) : IAsyncLifetime | |||
{ | |||
protected bool AttachedDebuggerToRemoteProcess { get; set; } = true; | |||
protected bool AttachedDebuggerToRemoteProcess { get; set; } = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Keboo please revert this before merging
#region DependencyProperty : IncreaseCommandProperty | ||
public ICommand? IncreaseCommand | ||
{ | ||
get => (ICommand?)GetValue(IncreaseCommandProperty); | ||
set => SetValue(IncreaseCommandProperty, value); | ||
} | ||
public static readonly DependencyProperty IncreaseCommandProperty = | ||
DependencyProperty.Register(nameof(IncreaseCommand), typeof(ICommand), typeof(NumericUpDown), new PropertyMetadata(null)); | ||
|
||
public object? IncreaseCommandParameter | ||
{ | ||
get => (object?)GetValue(IncreaseCommandParameterProperty); | ||
set => SetValue(IncreaseCommandParameterProperty, value); | ||
} | ||
public static readonly DependencyProperty IncreaseCommandParameterProperty = | ||
DependencyProperty.Register(nameof(IncreaseCommandParameter), typeof(object), typeof(NumericUpDown), new PropertyMetadata(null)); | ||
|
||
|
||
#endregion DependencyProperty : IncreaseCommandProperty | ||
|
||
#region DependencyProperty : DecreaseCommandProperty | ||
public ICommand? DecreaseCommand | ||
{ | ||
get => (ICommand?)GetValue(DecreaseCommandProperty); | ||
set => SetValue(DecreaseCommandProperty, value); | ||
} | ||
public static readonly DependencyProperty DecreaseCommandProperty = | ||
DependencyProperty.Register(nameof(DecreaseCommand), typeof(ICommand), typeof(NumericUpDown), new PropertyMetadata(default(ICommand?))); | ||
|
||
public object? DecreaseCommandParameter | ||
{ | ||
get => (object?)GetValue(DecreaseCommandParameterProperty); | ||
set => SetValue(DecreaseCommandParameterProperty, value); | ||
} | ||
|
||
public static readonly DependencyProperty DecreaseCommandParameterProperty = | ||
DependencyProperty.Register(nameof(DecreaseCommandParameter), typeof(object), typeof(NumericUpDown), new PropertyMetadata(null)); | ||
|
||
#endregion DependencyProperty : DecreaseCommandProperty |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me know if I am completely off the rails here, but here are my thoughts.
I think these commands are simply left-overs from when the XAML was using them. And I agree with you on-stream-comment that is not common practice for a custom control; you should rely on the template parts and deal with this stuff in the code-behind.
Also, in their current state, I really don't think they should be part of the public API for a NumericUpDown
. If you look at a Slider for example, it does expose some static RoutedCommands
to modify the value, but they don't have public setters. This way the calling code is not involved in determining whether Command.CanExecute
returns true/false which would be a really weird thing; it is the control itself that has the knowledge to determine this, not the caller. The commands are still exposed so they can be bound to and thus executed in custom UI/flows.
if (IncreaseCommand?.CanExecute(IncreaseCommandParameter) ?? false) | ||
IncreaseCommand.Execute(IncreaseCommandParameter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related to my comment above, this feels weird to me. The command should be used to actually change the value, not be executed once the value has changed. For that, there is a ValueChanged
RoutedEvent
.
if (e.Delta > 0) | ||
{ | ||
OnIncrease(); | ||
e.Handled = true; | ||
} | ||
else if (e.Delta < 0) | ||
{ | ||
OnDecrease(); | ||
e.Handled = true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it is an actual issue, but this will not mark the event as handled if e.Delta == 0
which seems a bit strange.
Imagine if the control is located in a ScrollViewer
, it has keyboard focus, and the user uses the scroll wheel to change the values. Would there be a scenario where you think you are scrolling the values, but hit the edge case and suddenly the ScrollViewer
scrolls instead because the event bubbles up? That would be annoying!
Padding="8,4" | ||
Command="{TemplateBinding DecreaseCommand}"/> | ||
|
||
<TextBox x:Name="PART_TextBoxField" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a reply to one of your comments @Keboo.
UPDATE:
While working on the TimePicker
style, I think I have managed to leverage the existing TextBox
styles. So for controls like these that "look" like a TextBox
, we simply hijack one of the padding parameters to be able to add content on top of the TextBox
but giving the appearance that the content is inside the TextBox
. Of course this only really works when content is added on the far right/left but that is often the case. So for this particular control, we could leverage the TextBox
style, but make the right padding big enough to fit in the plus/minus buttons. That way we get all the TextBox
goodness out of the box, and simply need to add the sugar on top (the extra buttons).
My original comment:
I think, similar to some of the other controls that "host" a TextBox
, we probably want to strip that particular TextBox
of all the fancy MDIX stuff and implement it directly in the template for the NumericUpDown
.
In other words, I assume this should eventually include all the prefix-/suffix-texts, leading-/trailing-icons, SmartHint
, etc. If you look at some of the other controls (ComboBox
for example), you will see that those things are handled in the "host" template, and not leveraging a "styled" TextBox
.
To elaborate on the above. Today we cannot easily leverage a "styled" Textbox
with the way our triggers are working today I believe, and therefore we end up having to duplicate a lot of the stuff (you'll see that in the other control styles). It may be a future refactoring task to see if we can somehow leverage a "styled" TextBox
in the controls that nests one of those rather than having to handle all the fancy stuff in the "host" template.
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" /> | ||
|
||
<RepeatButton x:Name="PART_DecreaseButton" | ||
Content="{local:PackIcon Kind=Minus}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the PackIcons
used for the plus/minus buttons should be exposed as dependency properties defaulting to the values you have set here. That gives a caller better control of what to show in the button.
Possibly it shouldn't even be a PackIcon
but simply an object
in case we want callers to be able to add arbitrary content to these buttons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a good point, just expose the button's content and let consumers do what they like with it.
|
||
<RepeatButton x:Name="PART_DecreaseButton" | ||
Content="{local:PackIcon Kind=Minus}" | ||
Style="{StaticResource MaterialDesignFlatButton}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If/when we introduce more styles for this control (e.g. "Floating", "Filled", and "Outlined"), the MaterialDesignFlatButton
style hardcoded here should probably be a parameter passed into the base style (internal DP/AP?).
Alternatively a dedicated RepeatButtonStyle
can be passed in from the style-override.
</Setter> | ||
</Style> | ||
|
||
<Style TargetType="wpf:NumericUpDown" BasedOn="{StaticResource MaterialDesignNumericUpDown}" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These default implicit styles for the custom controls are typically set up in Generic.xaml
; see here.
However, I actually prefer them to be here directly in the style. This is where the responsibility lies, and these resource dictionaries are pulled into Generic.xaml
anyway. To strengthen this argument, as part of adopting the SmartHint
in TimePicker
, I am nesting a TextBox
and thus need to forward a style. That just pollutes Generic.xaml
with stuff like this which really belongs closer to the other explicit styles.
Pull Request: Adding NumericUpDown control to Material Design
Preface
Hello everyone,
This is my first contribution to a GitHub project, and I am excited to be a part of the MaterialDesignXamlToolkit community. I have been working on this NumericUpDown control for Material Design, and I believe it will be a valuable addition to the project.
I must admit that my lack of experience contributing to open-source projects has delayed me in committing to this code. However, I have decided that I don't want to delay it any further by waiting to complete all the planned improvements before submitting my contribution when there is a strong community that can help me out with my 1st contribution.
Since this is my first GitHub contribution, I would appreciate any feedback and advice you can provide. I am eager to learn from more experienced developers and improve my skills, so please do not hesitate to give me constructive criticism and suggestions for improvements. I am committed to contributing to this project and look forward to continuing to learn and improve.
Thank you for taking the time to review my contribution, and I look forward to your feedback.
Description
This pull request adds a new NumericUpDown control to the Material Design project. The control provides a user-friendly way to input numeric values and is designed to fit seamlessly into the Material Design UI.
Changes Made
Pending Potential Changes
Screenshots
Related Issues
Additional Notes
None