title: Error handling WPF - MVVM
body: <p>I've read many articles on how to validate data in WPF - MVVM, but have gotten even more confused than I started. </p>
  
  <p>What I'm trying to do is simply add a new row to my db. The validation checks if the device name (the object being inserted) is over 2 characters long <strong>AND</strong> I want to check for uniqueness, and this is where it becomes problematic.</p>
  
  <p>The <code>Model</code>, from my understanding should take care of its own validation: e.g. character length, email address validity (if it has an email property), etc. However, what about getting access to the data layer in order to check for uniqueness? The Model should not know anything about that layer (from my understanding). This validation rule, has now become a "business" rule.</p>
  
  <p>Here's my <strong><code>RegisterViewModel</code></strong>:</p>
  
  <pre><code>class RegisterViewModel : ViewModelBase, IDataErrorInfo
  {
  
      private string _DeviceName = "";
      public string DeviceName
      {
          get { return _DeviceName; }
          set
          {
              _DeviceName = value;
              OnPropertyChanged("DeviceName");
          }
      }
  
      public string Error
      {
          get
          {
              throw new NotImplementedException();
          }
      }
      // We'd also check for uniqueness here?
      public string this[string columnName]
      {
          get
          {
              string result = null;
              if (columnName == "DeviceName" &amp;&amp; String.IsNullOrEmpty(DeviceName))
              {
                  return "Device name is required";
              }
              return result;
          }
      }
  
      public RegisterViewModel()
      {
          DeviceName = System.Environment.MachineName;
      }
  
  
      public ICommand Register { get; set; }
  
  }
  </code></pre>
  
  <p>Of course, some would argue that <code>IDataErrorInfo</code> should be implemented in the <code>Model</code> class, and I would somewhat agree, but again, the whole uniqueness problem is still there.</p>
  
  <p>Here's my <strong><code>device</code></strong> Model:</p>
  
  <pre><code>public partial class device 
  {
      public int did { get; set; }
      public int uid { get; set; }
      public string Name { get; set; }
  }
  </code></pre>
  
  <p>And finally, the View</p>
  
  <pre><code>&lt;Window x:Class="IPdevices.Register"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          xmlns:local="clr-namespace:IPdevices"
          mc:Ignorable="d"
          Title="Register" Height="202.884" Width="417.007" Icon="logo31_nowriting.ico" ResizeMode="NoResize" WindowStartupLocation="CenterScreen"&gt;
      &lt;Grid&gt;
          &lt;GroupBox x:Name="groupBox" Header="Device" VerticalAlignment="Top" RenderTransformOrigin="0.877,2.187" Margin="10,10,10,0" Height="96"&gt;
              &lt;Grid Margin="0,0,3,3"&gt;
                  &lt;Grid.RowDefinitions&gt;
                      &lt;RowDefinition Height="47*"/&gt;
                      &lt;RowDefinition Height="49*"/&gt;
                  &lt;/Grid.RowDefinitions&gt;
                  &lt;Grid.ColumnDefinitions&gt;
                      &lt;ColumnDefinition Width="146*"/&gt;
                      &lt;ColumnDefinition Width="197*"/&gt;
                  &lt;/Grid.ColumnDefinitions&gt;
                  &lt;TextBox x:Name="textBox" Height="24" TextWrapping="Wrap"  VerticalAlignment="Top" Grid.Column="1" Margin="0,6,0,0" Text="{Binding Path=DeviceName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=true, NotifyOnValidationError=true}"&gt;
                      &lt;TextBox.Style&gt;
                          &lt;Style TargetType="TextBox"&gt;
                              &lt;Style.Triggers&gt;
                                  &lt;Trigger Property="Validation.HasError" Value="True"&gt;
                                      &lt;Setter Property="Background" Value="Red"/&gt;
                                      &lt;Setter Property="ToolTip"
                                          Value="{Binding RelativeSource={x:Static RelativeSource.Self},
                                          Path=(Validation.Errors)[0].ErrorContent}"/&gt;
                                  &lt;/Trigger&gt;
                              &lt;/Style.Triggers&gt;
                          &lt;/Style&gt;
                      &lt;/TextBox.Style&gt;
                  &lt;/TextBox&gt;
                  &lt;Label x:Name="label" Content="Device Name:" RenderTransformOrigin="1.372,1.475" Margin="10,2,10,0" Height="28" VerticalAlignment="Top"/&gt;
                  &lt;TextBox x:Name="textBox1" Height="23" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Margin="0,7,0,0" Grid.Row="1" Grid.Column="1"/&gt;
                  &lt;Label x:Name="label1" Content="Location:" Margin="10,3,10,0" Grid.Row="1" Height="27" VerticalAlignment="Top"/&gt;
              &lt;/Grid&gt;
          &lt;/GroupBox&gt;
          &lt;Button x:Name="button" Content="Register" Height="25" VerticalAlignment="Top" Margin="10,129,10,0" IsDefault="True" ToolTip="Register" Command="{Binding Register}"/&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  
  <p>At this point, the validation works, and a red outline pops up. Though I'm not sure about how to deal with uniqueness property for the device name. On top of that, how do I allow the Register button become active only when everything passes? </p>
  
  <p>Any input would be appreciated.</p>