Lets start by looking at the correct way to bind to an enumeration. You use an ObjectDataProvider like this...
Start a new C#, WPF project called DisableComboBoxItem. Add references to Infragistics, Infragistics Editors, and Infragistics Data Presenters so your References tree looks like this...
The XAML contains an ObjectDataProvider and a XamDataGrid containing a single ComboBoxField column.
<Window x:Class="DisableComboBoxItem.MainWindow"
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:DisableComboBoxItem"
xmlns:igDP="http://infragistics.com/DataPresenter"
xmlns:igWPF="http://schemas.infragistics.com/xaml/wpf"
xmlns:System="clr-namespace:System;assembly=mscorlib"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<ObjectDataProvider x:Key="enumItems" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:eItems"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<igDP:XamDataGrid DataSource="{Binding Things}">
<igDP:XamDataGrid.FieldLayouts>
<igDP:FieldLayout>
<igDP:ComboBoxField Label="Items" Name="Item" ItemsSource="{Binding Source={StaticResource enumItems}}">
</igDP:ComboBoxField>
</igDP:FieldLayout>
</igDP:XamDataGrid.FieldLayouts>
</igDP:XamDataGrid>
using System.Collections.Generic;
using System.Windows;
namespace DisableComboBoxItem
{
public enum eItems
{
Locked,
Unlocked,
Extracted
}
public class cThing
{
public eItems Item { get; set; }
}
public partial class MainWindow : Window
{
private List<cThing> _Things = new List<cThing>
{
new cThing() {Item=eItems.Locked },
new cThing() {Item=eItems.Unlocked}
};
public List<cThing> Things { get { return _Things;
} }
public MainWindow()
{
InitializeComponent();
}
}
}
ComboBoxField bound to enum |
Now for the tricky part. We want to disable the Extracted option. The enum is already defined so all we have to work with is the text. It's not ideal, but it is what it is. The first thing is to realize that the ComboBoxField uses a XamComboEditor to drop the list. This contains a regular ComboBox which itself contains ComboBoxItems. We have to drill all the way down to the ComboBoxItems and change their style in order to disable one of them. We will set the style using a converter.
Add a class to the project called Converters and add this converter to it.
using System;
using System.Globalization;
using System.Windows.Data;
namespace DisableComboBoxItem
{
public class EnabledConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (value.ToString() != "Extracted");
}
public object
ConvertBack(object value,
Type targetType, object
parameter, CultureInfo culture)
{
throw new
NotImplementedException();
}
}
}
<Window.Resources>
<ObjectDataProvider x:Key="enumItems" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:eItems"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<local:EnabledConverter x:Key="EnabledConverter"/>
</Window.Resources>
Now insert this styling into the ComboBoxField
<igDP:ComboBoxField Label="Items" Name="Item" ItemsSource="{Binding Source={StaticResource enumItems}}">
<igDP:ComboBoxField.Settings>
<igDP:FieldSettings EditorType="{x:Type igWPF:XamComboEditor}">
<igDP:FieldSettings.EditorStyle>
<Style TargetType="{x:Type igWPF:XamComboEditor}">
<Setter Property="ComboBoxStyle">
<Setter.Value>
<Style TargetType="ComboBox">
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ComboBoxItem">
<Setter Property="IsEnabled" Value="{Binding RelativeSource={RelativeSource Self}, Path=DataContext, Converter={StaticResource EnabledConverter}}"/>
</Style>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
</igDP:FieldSettings.EditorStyle>
</igDP:FieldSettings>
</igDP:ComboBoxField.Settings>
</igDP:ComboBoxField>
ComboBoxField with disabled item |
Add a Class Library project to the solution using its default name of ClassLibrary1. It will have a single class called Class1. Move the enum into that class.
Because the enum is in a different namespace, we need a new xmlns declaration.
xmlns:cl1="clr-namespace:ClassLibrary1;assembly=ClassLibrary1"
You might think you would just change the TypeName to
<x:Type TypeName="cl1:Class1.eItems"/>
Try it, you will get an intellisense error about embedded types or a run time error message that it can't find Class1.eItems. Something about the XAML interpreter expects a property after a period. Classes, structures, and enums confuse it. There is a special syntax to get around this issue. Try this instead.
<x:Type TypeName="cl1:Class1+eItems"/>
No comments:
Post a Comment