> **View** <!-- language-all: lang-xaml --> The XAML is rather... simplistic: ![designer rendition of XAML code][1] Each label and textbox (and the <kbd>Save</kbd> button) stretches all the way across the window. Instead of just *dumping* controls into a `StackPanel`, you could consider leveraging automagic layout with a `WrapPanel`, and making each label+textbox duet logically regrouped. I like that you have no WinForms-like absolute positioning, but I would have expected to see margins, or styles. I'd recommend further nesting in your XAML - use a `Grid` to define sections, regroup label+textbox fields in their own `StackPanel`, and use styles to make all fields feel the same, without having to set `MinWidth` and fonts and other things every time. ![Grid, GroupBox, WrapPanel, margins, padding and styles make a prettier UI][2] Having your controls *logically* regrouped also *visually* regroups them, and your user has a better experience. Here I've removed the "Work Order Name" textblock, and replaced it with a `GroupBox`. Here's the XAML markup for the above screenshot, I'd like to highlight this part: > <WrapPanel DataContext="{Binding SelectedWorkOrder}"> Setting the container's data context allows everything under it to bind to the `SelectedWorkOrder` properties without having to qualify them, which makes clearer markup. <Grid Margin="4"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> <RowDefinition Height="32" /> </Grid.RowDefinitions> <GroupBox Grid.Row="0" Padding="4" Header="Work Order Name"> <TextBox Text="{Binding WorkOrderName}" AcceptsReturn="False"> <TextBox.InputBindings> <KeyBinding Key="Enter" Command="{Binding GetWorkOrderCommand}" /> </TextBox.InputBindings> </TextBox> </GroupBox> <GroupBox Grid.Row="1" Padding="4" Header="Work Order Info" IsEnabled="{Binding IsNewWorkOrder}"> <WrapPanel DataContext="{Binding SelectedWorkOrder}"> <StackPanel Margin="2"> <TextBlock Text="Part Number"/> <TextBox Style="{StaticResource InputField}" Text="{Binding PartNumber}"/> </StackPanel> <StackPanel Margin="2"> <TextBlock Text="Created"/> <TextBox Style="{StaticResource InputField}" Text="{Binding Created}"/> </StackPanel> <StackPanel Margin="2"> <TextBlock Text="Closed"/> <TextBox Style="{StaticResource InputField}" Text="{Binding Closed}"/> </StackPanel> <StackPanel Margin="2"> <TextBlock Text="First Number"/> <TextBox Style="{StaticResource InputField}" Text="{Binding FirstNumber}"/> </StackPanel> <StackPanel Margin="2"> <TextBlock Text="Last Number"/> <TextBox Style="{StaticResource InputField}" Text="{Binding LastNumber}"/> </StackPanel> </WrapPanel> </GroupBox> <Button Grid.Row="2" Content="Save"/> </Grid> Comments in XAML shouldn't try to explain anything: > <!--This textbox is incharge of searching the work order in the DB. [...] I hope not. A textbox shouldn't be *in charge of* anything but collecting user input and displaying a value. This comment is misleading at best, and tries to explain the mechanics of the *ViewModel*, which has nothing to do with the textbox itself - help yourself, remove it. --- I'm not sure why you're passing your command a parameter here: > <TextBox Text="{Binding WorkOrderName}" AcceptsReturn="False"> > <TextBox.InputBindings> > <KeyBinding Key="Enter" Command="{Binding GetWorkOrderCommand}" > CommandParameter="{Binding Path=Text, > RelativeSource={RelativeSource AncestorType=TextBox}}"/> > </TextBox.InputBindings> > </TextBox> The *ViewModel* already knows what the `WorkOrderName` is, so the command binding can be simplified: > <TextBox Text="{Binding WorkOrderName}" AcceptsReturn="False"> > <TextBox.InputBindings> > <KeyBinding Key="Enter" Command="{Binding GetWorkOrderCommand}" /> > </TextBox.InputBindings> > </TextBox> --- > **Model** Not much to say about the `WorkOrder` model, except that I find auto-properties don't really need the whitespace in-between: <!-- language: lang-csharp --> public class WorkOrder { public int WorkOrderId { get; set; } public string WorkOrderName { get; set; } public string PartNumber { get; set; } public DateTime Created { get; set; } public DateTime? Closed { get; set; } public long FirstNumber { get; set; } public long LastNumber { get; set; } } This class is an *entity type* - I don't like that the *View* is binding directly to it. I would create another class, a `WorkOrderViewModel`, that implements the `INotifyPropertyChanged` interface - this class only needs to expose the properties of the *Model* that the *View* is interested in, and can easily know whether it's a "new" work order: <!-- language: lang-csharp --> public class WorkOrderViewModel : INotifyPropertyChanged { private readonly WorkOrder _entity; public WorkOrderViewModel() : this(new WorkOrder()) { } public WorkOrderViewMode(WorkOrder entity) { _entity = entity; } public WorkOrder Model { get { return _entity; } } public string WorkOrderName { get { return _entity.WorkOrderName; } set { _entity.WorkOrderName = value; NotifyPropertyChanged("WorkOrderName"); } } // ... public bool IsNew { get { return _entity.WorkOrderId == 0; } } } --- > **ViewModel** The `WorkOrderManagerViewModel` can then expose `SelectedWorkOrder` as a `WorkOrderViewModel`. **Comments** Again, the comments in the *ViewModel* should explain what's going on *in the ViewModel*, not in the *View* - this is a *waiting-to-become-a-blatant-lie* comment: <!-- language: lang-csharp --> > //bound to the work order name textbox This one is also not clear: <!-- language: lang-csharp --> > //on text changed - clear all values "clearing all values" is the result of setting the `SelectedWorkOrder` to `null`... but only because of things that happen outside the *ViewModel* (specifically, because of the bindings in the *View*) - the comment would be better if reworded like this: <!-- language: lang-csharp --> // text has changed, invalidate current selection. This one is also something that the *ViewModel* has no control over: <!-- language: lang-csharp --> > //after enter was pressed - used to search if exists or not If the command bindings change in the *View*, this commment becomes wrong, or incomplete - what if you added a <kbd>Search</kbd> button next to the text box, for convenience? What if more controls were added, with command bindings to this command? Other than that, I find the name `GetWorkOrder` a little bit awkward for a method that returns `void`. I like naming my command methods `CanExecuteXxxxx` and `ExecuteXxxxx` - so that would be `CanExecuteGetWorkOrder` and `ExecuteGetWorkOrder` - these names also help justifying the `object` parameter that the `ICommand` interface wants. --- The `CanSave` logic could be simplified: <!-- language: lang-csharp --> > if (SelectedWorkOrder == null) > return false; > > return true; Is really nothing more than `return SelectedWorkOrder != null;`. [1]: https://i.sstatic.net/9cOsO.png [2]: https://i.sstatic.net/2gpuC.png