Question

I have a combobox and button on my form. The combobox has categories in them. I want to allow/disallow pending on if they are a 'system category' based on a boolean.

Here is my xaml:

<Window.Resources>
    <Style TargetType="{x:Type ComboBox}">
        <Style.Triggers>
            <Trigger Property="Validation.HasError" Value="true">
                <Setter Property="ToolTip"
                Value="{Binding RelativeSource={RelativeSource Self}, 
                       Path=(Validation.Errors)[0].ErrorContent}"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

This is the stack panel with the two controls in them:

                <StackPanel Grid.Column="1" Grid.Row="1">
                    <Label Content="Delete Category" Height="28"/>
                    <ComboBox x:Name="comboBox_DeleteCategory" 
                              Grid.Row="1" 
                              Height="29"                                  
                              ItemsSource="{Binding Path=CategorySelected.Items, ValidatesOnDataErrors=true, NotifyOnValidationError=true}"
                              SelectedItem="{Binding Path=CategorySelected.SelectedItem ,ValidatesOnDataErrors=True, NotifyOnValidationError=true}" 
                              DisplayMemberPath="Name"/>
                    <Button Content="Delete" Height="25" Margin="0,5,0,0" HorizontalAlignment="Right" Width="103.307" Command="{Binding DeleteCommand}"/>
                </StackPanel>

I am trying to get the combobox to show a tooltip if it is determined that it is a system category.

The DeleteCommand is working fine so I am not having issues with the button being disabled when I get a hit on the system category.

This is my code to show the tooltip:

#region IDataErrorInfo Members

public string Error { get; set; }

public string this[string columnName]
{
  get
  {
    Error = "";
    switch (columnName)
    {
      case "comboBox_DeleteCategory":
        if (CategorySelected.SelectedItem != null && CategorySelected.SelectedItem.IsInternal)
        {
            Error = CategorySelected.SelectedItem.Name + " is an system category and cannot be deleted.";
            break;
        }
        break;

    }

    return Error;
  }
}

#endregion

Any suggestions?

Thanks,

Eroc

Was it helpful?

Solution

The indexer (public string this[string columnName]) is called with the property name that has been changed by the latest binding update. That is, filtering for "comboBox_DeleteCategory" (the control name) won't help here. You have to filter for the property that was updated by the control's binding and determine if it is in the expected state. You can put a breakpoint in the indexer and watch the columnName's value. What is more, the Error property is not used by WPF at all. Thus, it is not necessary to set it. A simple example:

public class Contact : IDataErrorInfo, INotifyPropertyChanged
{
     private string firstName;
     public string FirstName
     {
         // ... set/get with prop changed support
     }

     #region IDataErrorInfo Members

     public string Error
     {
         // NOT USED BY WPF
         get { throw new NotImplementedException(); }
     }

     public string this[string columnName]
     {
        get 
        {
            // null or string.Empty won't raise a validation error.
            string result = null;

            if( columnName == "FirstName" )
            {
                if (String.IsNullOrEmpty(FirstName))
                     result = "A first name please...";
                else if (FirstName.Length < 5)
                     result = "More than 5 chars please...";
             }

            return result;
    }
}

#endregion

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top