title: Why are the datagrid delete command buttons disabled?
body: <p>I have a DataGrid where each row has a delete button.  If I set the <code>Command="Delete"</code> attribute on the Delete button element in XAML, the button is disabled at runtime.  Why??</p>
  
  <p>XAML:</p>
  
  <pre><code>&lt;Page x:Class="AxureExport.TargetPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:AxureExport"
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400"
    Title="Define Export Targets"
    Loaded="Page_Loaded"&gt;
  
  &lt;Page.Resources&gt;
      &lt;Style TargetType="{x:Type DataGridCell}"&gt;
          &lt;EventSetter Event="PreviewMouseLeftButtonDown"
                       Handler="DataGridCell_PreviewMouseLeftButtonDown" /&gt;
      &lt;/Style&gt;
  &lt;/Page.Resources&gt;
  
  &lt;Grid&gt;
      &lt;Grid.ColumnDefinitions&gt;
          &lt;ColumnDefinition Width="7" /&gt;
          &lt;ColumnDefinition Width="65" /&gt;
          &lt;ColumnDefinition Width="458*" /&gt;
          &lt;ColumnDefinition Width="47" /&gt;
          &lt;ColumnDefinition Width="10" /&gt;
      &lt;/Grid.ColumnDefinitions&gt;
      &lt;Grid.RowDefinitions&gt;
          &lt;RowDefinition Height="7" /&gt;
          &lt;RowDefinition Height="63*" /&gt;
      &lt;/Grid.RowDefinitions&gt;
      &lt;!-- target file --&gt;
      &lt;TextBlock Name="textBlock3"
                 Text="2. Select the location where you want to save the string files:"
                 Height="23"
                 HorizontalAlignment="Left"
                 Margin="5,0,0,0"
                 VerticalAlignment="Top"
                 Grid.Row="2"
                 Grid.Column="1"
                 Grid.ColumnSpan="4"
                 Width="441" /&gt;
      &lt;TextBlock Name="textBlock4"
                 Text="(Warning: This tool overwrites files in the target folder.)"
                 Height="16"
                 HorizontalAlignment="Left"
                 Margin="54,15,0,0"
                 VerticalAlignment="Top"
                 Width="256"
                 FontStyle="Italic"
                 FontWeight="Light"
                 FontSize="10"
                 Grid.Row="2"
                 Grid.Column="1"
                 Grid.ColumnSpan="2" /&gt;
      &lt;TextBlock Name="textBlock5"
                 Text="Target:"
                 Height="23"
                 HorizontalAlignment="Left"
                 Margin="22,30,0,238"
                 VerticalAlignment="Center"
                 Grid.Row="1"
                 Grid.Column="1" /&gt;
      &lt;!-- ExportTargets Datagrid --&gt;
      &lt;DataGrid Name="ExportTargets"
                AutoGenerateColumns="False"
                Grid.Column="2"
                Grid.Row="1"
                Margin="0,71,0,63"
                ItemsSource="{Binding Path=., Mode=TwoWay}"
                SelectionUnit="Cell"
                GridLinesVisibility="None"
                RowDetailsVisibilityMode="Collapsed"
                CanUserReorderColumns="False"
                CanUserResizeColumns="False"
                CanUserResizeRows="False"
                RowHeaderWidth="40"
                IsSynchronizedWithCurrentItem="True"
                HorizontalScrollBarVisibility="Disabled"
                CanUserAddRows="True"
                CanUserDeleteRows="True"&gt;
          &lt;DataGrid.Resources&gt;
              &lt;SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
                               Color="Transparent" /&gt;
              &lt;SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
                               Color="Transparent" /&gt;
              &lt;SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}"
                               Color="Black" /&gt;
              &lt;SolidColorBrush x:Key="{x:Static SystemColors.ControlTextBrushKey}"
                               Color="Black" /&gt;
          &lt;/DataGrid.Resources&gt;
          &lt;DataGrid.Columns&gt;
              &lt;DataGridCheckBoxColumn Binding="{Binding IsXML, Mode=TwoWay}"
                                  Header="XML"
                                  CanUserSort="False"
                                  CanUserReorder="False" /&gt;
              &lt;DataGridCheckBoxColumn Binding="{Binding IsProperty, Mode=TwoWay}"
                                      Header="Property"
                                      CanUserSort="False"
                                      CanUserReorder="False" /&gt;
              &lt;DataGridTextColumn Binding="{Binding FolderName, Mode=TwoWay}"
                                  Header="Folder"
                                  Width="*"
                                  CanUserReorder="False"
                                  IsReadOnly="False" /&gt;
              &lt;DataGridTemplateColumn Header="Browse"&gt;
                  &lt;DataGridTemplateColumn.CellTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;Button Name="Browse"
                                  Command="{Binding BrowseCommand}"
                                  HorizontalAlignment="Center"
                                  Width="20"&gt;...&lt;/Button&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTemplateColumn.CellTemplate&gt;
              &lt;/DataGridTemplateColumn&gt;
              &lt;DataGridTemplateColumn Header="Delete" IsReadOnly="True"&gt;
                  &lt;DataGridTemplateColumn.CellTemplate&gt;
                      &lt;DataTemplate&gt;
                          &lt;Button Name="Delete"
                                  Command="{x:Static DataGrid.DeleteCommand}"
                                  HorizontalAlignment="Center"
                                  Width="20"
                                  IsEnabled="True"&gt;X&lt;/Button&gt;
                      &lt;/DataTemplate&gt;
                  &lt;/DataGridTemplateColumn.CellTemplate&gt;
              &lt;/DataGridTemplateColumn&gt;
          &lt;/DataGrid.Columns&gt;
      &lt;/DataGrid&gt;
      &lt;Button Name="NextButton"
              Content="Next"
              Grid.Column="2"
              Grid.ColumnSpan="2"
              Grid.Row="1"
              Margin="0,0,2,12"
              Width="100"
              Height="40"
              HorizontalAlignment="Right"
              VerticalAlignment="Bottom"
              Click="NextButton_Click" /&gt;
  &lt;/Grid&gt;
  &lt;/Page&gt;
  </code></pre>
  
  <p>Code-behind:</p>
  
  <pre><code>// DataTable
  using System.Windows;
  using System.Windows.Controls;
  using System.Windows.Input;
  
  namespace AxureExport {
  
  /// &lt;summary&gt;
  /// Interaction logic for TargetPage.xaml
  /// &lt;/summary&gt;
  public partial class TargetPage : Page {
  
      FrameWindow _frame;
      //ExportTargetInfos _eti;
  
      public TargetPage(FrameWindow frame) {
          InitializeComponent();
  
          _frame = frame;
          _frame.ExportTargets = new ExportTargetInfos(Properties.Settings.Default.ExportTargetHistory);
          this.DataContext = _frame.ExportTargets;
      }
  
      //
      // enable editing on single-click
      private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
          DataGridCell cell = sender as DataGridCell;
  
          if (!cell.IsEditing) {
              if (!cell.IsFocused)
                  cell.Focus();
  
              if (!cell.IsSelected)
                  cell.IsSelected = true;
          }
      }
  
      private void Page_Loaded(object sender, RoutedEventArgs e) {
      }
  
      private void NextButton_Click(object sender, RoutedEventArgs e) {
          Properties.Settings.Default.ExportTargetHistory = _frame.ExportTargets.GetExportTargets();
          _frame.NavigateTo(typeof(ExportPage));
      }
  }
  }
  </code></pre>
  
  <p>ViewModel:</p>
  
  <pre><code>using System;
  using System.Collections.ObjectModel;       // ObservibleCollection&lt;&gt;
  using System.Collections.Specialized;       // StringCollection
  using System.ComponentModel;                // INotifyPropertyChanged
  
  namespace AxureExport {
  public class ExportTargetInfos : ObservableCollection&lt;ExportTargetInfo&gt; {
  
      const char _SEP = '|';      // field seperator character
  
      // default constructor
      public ExportTargetInfos() : base() {
      }
  
      // copy constructors
      public ExportTargetInfos(ExportTargetInfos etis) : base() {
          if (etis == null) return;
          foreach (ExportTargetInfo eti in etis) {
              this.Add(new ExportTargetInfo(eti.FolderName, eti.IsXML, eti.IsProperty));
          }
      }
  
      public ExportTargetInfos(StringCollection sc) : base() {
          if (sc == null) return;
          foreach (string s in sc)
              Add(ParseExportTarget(s));
      }
  
      public StringCollection GetExportTargets() {
          StringCollection sc = new StringCollection();
  
          foreach (ExportTargetInfo et in this)
              sc.Add(BuildExportTarget(et));
  
          return sc;
      }
  
      // create a string from an ExportTarget (for persistance)
      private static string BuildExportTarget(ExportTargetInfo et) {
          return et.FolderName + _SEP + et.IsXML.ToString() + _SEP + et.IsProperty.ToString();
      }
  
      // create an ExportTarget from an unparsed string (for persistance)
      private static ExportTargetInfo ParseExportTarget(string s) {
          int count = s.Split(_SEP).Length - 1;
          string[] items = s.Split(new[] { _SEP }, StringSplitOptions.None);
          string name = (count &lt; 1 ? String.Empty : items[0]);
          bool isXML = (count &gt; 0 ? Convert.ToBoolean(items[1]) : false);
          bool isProp = (count &gt; 1 ? Convert.ToBoolean(items[2]) : false);
          return new ExportTargetInfo(name, isXML, isProp);
      }
  }
  
  //
  // represents an export target (folder plus options) in it's parsed form
  public class ExportTargetInfo : INotifyPropertyChanged {
  
      public event PropertyChangedEventHandler PropertyChanged;
  
      public IDelegateCommand BrowseCommand { protected set; get; }
  
      // default constructor is needed to enable datagrid to add rows
      public ExportTargetInfo() {
          _folderName = String.Empty;
          _isXML = false;
          _isProperty = false;
          this.BrowseCommand = new DelegateCommand(ExecuteBrowse, CanExecuteBrowse);
      }
  
      public ExportTargetInfo(string targetFolderName, bool isXML, bool isProperties) {
          _folderName = targetFolderName;
          _isXML = isXML;
          _isProperty = isProperties;
          this.BrowseCommand = new DelegateCommand(ExecuteBrowse, CanExecuteBrowse);
      }
  
      private string _folderName;
      public string FolderName {
          get { return _folderName; }
          set { SetProperty&lt;string&gt;(ref _folderName, value, @"FolderName"); }
      }
  
      private bool _isXML;
      public bool IsXML {
          get { return _isXML; }
          set { SetProperty&lt;bool&gt;(ref _isXML, value, @"IsXML"); }
      }
  
      private bool _isProperty;
      public bool IsProperty {
          get { return _isProperty; }
          set { SetProperty&lt;bool&gt;(ref _isProperty, value, @"IsProperty"); }
      }
  
      // browse button for selected row clicked
      void ExecuteBrowse(object param) {
          // use WPF-WinForms interop (:-p)
          var folderDialog = new System.Windows.Forms.FolderBrowserDialog();
          folderDialog.Description = "Please designate the target folder";
          folderDialog.SelectedPath = FolderName;
          folderDialog.ShowNewFolderButton = true;
          if (folderDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
              FolderName = folderDialog.SelectedPath;
      }
  
      bool CanExecuteBrowse(object param) {
          return true;
      }
  
      protected bool SetProperty&lt;T&gt;(ref T storage, T value, string propertyName = null) {
          if (object.Equals(storage, value))
              return false;
  
          storage = value;
          OnPropertyChanged(propertyName);
          return true;
      }
  
      protected void OnPropertyChanged(string propertyName) {
          if (PropertyChanged != null)
              PropertyChanged( this, new PropertyChangedEventArgs(propertyName));
      }
  }
  }
  </code></pre>
  
  <p>Does anyone have insight as to what's the cause?  </p>