WPF XamComboEditor/ComboEditorTool - Setting default text - c#

I'm trying to add some default text to combo boxes that will show when there is no item selected. I'm using a style to acheive this which works great when the combo is first loaded.
<Style TargetType="{x:Type igRibbon:ComboEditorTool}" x:Key="PleaseSelect">
<Style.Triggers>
<Trigger Property="SelectedIndex" Value="-1">
<Setter Property="Text" Value="Please Select" />
</Trigger>
</Style.Triggers>
</Style>
<igRibbon:ComboEditorTool Style="{StaticResource PleaseSelect}"
ItemsSource="{Binding MyItems}" SelectedItem="{Binding MySelectedItem }" />
But when the combo's selected item is reset (by setting it to null, which sets the SelectedIndex to -1) it fails to display the default text (even though the the trigger does fire), what could be the reason for this? Is there a better way to reset the selected item?
Cheers
Here is the solution that I used, thanks to #AlexPaven for the idea:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
{
return "Please Select";
}
else
{
return value;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is string && ((string)value) == "Please Select")
{
return null;
}
else
{
return value;
}
}

I'm not familiar with the Infragistics suite, but I suspect it's the same thing as with regular combo boxes: since you have a binding on SelectedItem, the Text cannot be set to an item that blatantly disobeys that binding; the Text IS a representation of the SelectedItem. If the SelectedItem is null, then the Text must also be a representation of null.
I'm guessing (didn't try it and I may be just plain wrong) you could probably accomplish this with an IValueConverter that returns a custom string when the passed object is null (and returns the object unchanged otherwise), set on the SelectedItem binding.

It's been a while since this question was asked, but let me answer it with a more Infragistics related answer.
Let's start with a short side node:
We have to be careful when using XamComboEditor without specifying the namespace,
because in the Infragistics Framework the class is defined two times.
1. Infragistics.Windows.Editors.XamComboEditor
2. Infragistics.Controls.Editors.XamComboEditor
Referring to the Infragistics Help, the recommended one is the Infragistics.Windows.Editors.XamComboEditor
See the About xamComboEditor:
We recommend that you use the xamComboEditor control instead of the xamComboEditor (Input) control. The xamComboEditor (Input) is being planned for retirement over the next few years and will not receive any new features.
And now to your question:
Both, the Infragistics.Windows.Editors.XamComboEditor and the derived Infragistics.Windows.Ribbon.ComboEditorTool, have a property for setting a default text for null values. This property is called:
NullText
The text to display when the value of the editor is null and the editor is not in edit mode. The default value is empty string. (Inherited from Infragistics.Windows.Editors.TextEditorBase)
Also the Infragistics.Controls.Editors.XamComboEditor provides such a property. It is called:
EmptyText
Gets/Sets the Text that should be displayed when the editor doesn't have anything selected. (Inherited from Infragistics.Controls.Editors.ComboEditorBase)
Example for ComboEditorTool:
Referencing the following dlls:
InfragisticsWPF4.Editors.v18.1
InfragisticsWPF4.Ribbon.v18.1
InfragisticsWPF4.v18.1
xaml-Snippet:
xmlns:ribbon="http://infragistics.com/Ribbon"
...
<ribbon:ComboEditorTool Id="SampleComboEditorTool"
NullText="Select ..."
ItemsSource="{Binding }"
/>
Screenshot:
Example for Infragistics.Windows.Editors.XamComboEditor:
Referencing the following dlls:
InfragisticsWPF4.Editors.v18.1
InfragisticsWPF4.v18.1
xaml-Snippet:
xmlns:editors="http://infragistics.com/Editors"
...
<editors:XamComboEditor Width="120" Height="23"
ItemsSource="{Binding}"
NullText="Select ..."
/>
Screenshot:
Example for Infragistics.Controls.Editors.XamComboEditor:
Referencing the following dlls:
InfragisticsWPF4.Controls.Editors.XamComboEditor.v18.1
InfragisticsWPF4.v18.1
xaml-Snippet:
xmlns:ig="http://schemas.infragistics.com/xaml"
...
<ig:XamComboEditor Width="120" Height="23"
ItemsSource="{Binding}"
EmptyText="Select ..."
/>
Screenshot:
Second side note: the first occurrence I've found for the property NullText was in the Help Doc of Version 2012.1. See here

Related

Select one of two wpf implementations with a bool variable

In my application I want to switch between editing and just displaying data in my view.
In order to edit them I have textboxes. For Displaying I am using textblock.
Some of the Data is displayed inside a ListView.
In my ViewModel I have variables called "IsEditingMode" and "IsNotEditingMode" to determine the state of the view.
Now I want something like this in wpf:
<switch betwen implementation>
<use textbox if IsEditingMode>
<use textblock if IsNotEditingMode>
I tried this using Converters to change the Visibility of the textbox and the textblock:
Converter:
public class BoolToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var boolValue = (bool)value;
if (boolValue)
return Visibility.Visible;
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Provide the Converter a Resource:
<helper:BoolToVisibilityConverter x:Key="IsVisibleConverter"/>
Use the converter to change the Visibility of the elements in my xaml:
<StackPanel>
<TextBlock Text ="{Binding TextVariableInVM}" Visibility="{Binding IsNotEditingMode, Converter={StaticResource IsVisibleConverter}}"/>
<TextBox Text ="{Binding TextVariableInVM}"
Visibility="{Binding IsEditingMode,
Converter={StaticResource IsVisibleConverter}}"/>
</StackPanel>
The result is:
Editing mode: The Textbox is displayed
Not editing mode: The TextBlock is displayed
For a small number of displayed variables this is just fine.
In my real application I have a huge amount of displayed variables and some of them are displayed using listview.
In that case my UI is getting really slow.
I believe that this is due to the fact that I bind each variable twice.
Is there a more elegant solution to do that editing <-> not editing switch?
Why not use only a TextBox element for both situations?
TextBox has a property called IsReadOnly that you can set to true or false depending on your action.
Is this code enough for your need's?
It's a TextBox that binds your text, and changes from edit mode or not.
<TextBox Text="{Binding TextVariableInVM}" IsReadOnly="{Binding IsNotEditingMode}"/>
If you complain about UI being slow, this example will be faster and more elegant because:
Doesn't need a StackPanel
One text element instead of two
Just one extra property needed to check if is editable or not
Doesn't need to convert from Boolean to Visibility
You may also want to remove the TextBox Border when it is read-only by a Style like this:
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Trigger>
</Style.Triggers>
</Style>

How to bind WPF control text to boolean, and make decision about text in xaml

I have a button control in a WPF application which is used for log-in purposes. The button is dual purpose: when logged-out, it shall display the text "log in". When logged-in, it shall display the text "log out".
I could do this with databinding to an appropriate string property in the viewmodel.
But it would be neater if I could simply databind to the "loggedIn" boolean (false for logged-out, true for logged-in) and then make the decision about what text to display on the button from within the view.
Is this possible?
You can achieve it using Style in Xaml without writing specific C# code.
Suppose you have IsLoggedIn property in ViewModel which is being changed on button bind command's execute method :
private void MyButtonCommandExecuteMethod()
{
this.IsLoggedIn = !this.IsLoggedIn;
}
private bool isLoggedIn;
public bool IsLoggedIn
{
get
{
return this.isLoggedIn;
}
set
{
this.isLoggedIn = value;
OnPropertyChanged(nameof(IsLoggedIn));
}
}
In the above code OnPropertyChanged is method implementation of INotifyPropertyChanged's PropertyChanged event. If you using any framework or defined own name, then replace it with appropriate name.
You could define a style such as:
<Button Command="{Binding YourButtonCommand}">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Content" Value="Log In" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsLoggedIn}" Value="True">
<Setter Property="Content" Value="Log out" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
In the above code IsLoggedIn is bind to DataTrigger to update the Button's Content property based on it's value.
Another point, the button style is inherited from default style. If you any Keyed style then use it in BasedOn Property.
Solution
Yes that is possible using value converter, specifically IValueConverter. You can bind a bool property, say BoolProperty from your viewmodel to button using converter like this.
<Button Content="{Binding BoolProperty, Converter={StaticResource BoolConverter}}" />
Step 1: You need to create a converter that will accept bool value and return whatever string as you wish.
public class BoolConverter : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool)
{
return value.ToString();
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Step 2: Declare this converter as a resource in XAML (you will need to define local namespace alias that contains the converter in your <Window ..> start element.
<local:BoolConverter x:Key="BoolConverter" />
So now whenever property changed event is raised for BoolProperty, this converter will be triggered and button text will change appropriately.
Suggestion:
I am not sure why you think maintaining extra string property is not a clean way. It is clean and is much simpler approach than using converter. Whatever I have shown is unnecessary overhead for your case, IMO. However, since you asked about possibility, I detailed it. Choice is yours! :)

Validation on Radio Buttons

I'm not really sure how to word this, so here goes.
I've got some radio buttons on a form in my WPF application which get validated. They're basically a required field for this form.
When I start to fill in the form, both radio buttons are marked with a red border, however when I select one of the buttons. This happens:
How do I go about fixing this? I know I could change the control to something like a ComboBox or something, but typically gender fields on an electronic form are radio buttons.
I've tried getting the validation to display on the stackpanel containing the radio buttons, it's done nothing.
I can't really set a default value for the gender either incase it gets overlooked and causes a complaint/misunderstanding further down the line.
The XAML for the image above is here:
<StackPanel Grid.Column="1" Grid.Row="3" Orientation="Horizontal">
<RadioButton GroupName="Gender" Content="Male" IsChecked="{Binding Gender, Converter={StaticResource GenderToCharConverter}, ConverterParameter=M}"/>
<RadioButton GroupName="Gender" Content="Female" IsChecked="{Binding Gender, Converter={StaticResource GenderToCharConverter}, ConverterParameter=F}"/>
</StackPanel>
Edit: To clarify a bit more on what my problem is, when I open a new instance of this form, both radio buttons are marked with validation borders as they should be as Gender is a required field on this form.
When a gender is selected, the validation border is only removed from the radio button that is clicked when really I would imagine that both borders should be removed as the data-bound property now has a value.
The only way it seems to remove this border is to click the other option to remove and then re-select the original value. This shouldn't happen on this form as this could confuse the users and have them mistakingly think that there's still a problem with the gender controls, and furthermore it just looks like a bug.
Edit 2: This question fixes the border showing, but then hides the fact that one of the radio buttons selected is required. Is there not some way to put a border around the StackPanel instead rather than the individual radio buttons. It seems there is absolutely no examples on how to achieve this on Google, which is completely stupid.
Edit 3: Relevant code.
// Gender property in the viewmodel.
[Required(AllowEmptyStrings=false, ErrorMessage="Gender is a required field.")]
public string Gender
{
get { return _currentMember.Gender; }
set
{
if(value != _currentMember.Gender)
{
_currentMember.Gender = value;
RaisePropertyChanged();
Validate(_currentMember.Gender);
}
}
}
// Converter
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string input = (string)value;
string test = (string)parameter;
return input == test;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null || !(value is bool))
return string.Empty;
if (parameter == null || !(parameter is string))
return string.Empty;
if ((bool)value)
return parameter.ToString();
else
return string.Empty;
}
In my opinion you have 2 solutions: the first one - the easiest one - is to set a default for Gender property. In this way one among the two radiobuttons will be check and the "required" attribute will be always satisfied.
The second solution is to "mask" a ListView as a RadioButtonGroup. For my example I used a very intuitive framework to perform validation by using attributes. You can find it here.
So, instead of using a stackpanel, I wrote this piece of XAML:
<ListView SelectedValue="{Binding Gender, ValidatesOnDataErrors=True}"
SelectedValuePath="Tag" BorderThickness="0" Margin="2" SelectionMode="Single">
<RadioButton GroupName="Gender" Margin="2" Tag="M" Content="Male" IsChecked="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsSelected}" />
<RadioButton GroupName="Gender" Margin="2" Tag="F" Content="Female" IsChecked="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsSelected}" />
</ListView>
Of course the ListView can be improved with a more suitable style (which for example hides the selection style). Since just the SelectedValue property is binded to the Gender property, you will see just one validation template around the ListView.
I hope this is the result you were looking for.
Moreover - with the that framework - I could not reproduce your issue, since if I use your stackpanel and I check one radiobutton, both the red rectangles will disappear.
Here's how to do this without the framework in the other answer (which is nice but not essential).
The key is to surround the radio buttons with another element, which has a binding to the same property. This will display the error. I set a binding for the Tag property of a StackPanel, which is otherwise not used.
Then you need to turn off the validation error template for each radio button, using 'Validation.ErrorTemplate="{x:Null}"'.
<StackPanel Tag="{Binding Gender}" >
<RadioButton IsChecked="{Binding Gender,
Converter={StaticResource GenderConverter},
ConverterParameter={x:Static enumerations:Male}}"
Content="Male" Validation.ErrorTemplate="{x:Null}"/>
<RadioButton IsChecked="{Binding Gender,
Converter={StaticResource GenderConverter},
ConverterParameter={x:Static enumerations:Female}}"
Content="Female" Validation.ErrorTemplate="{x:Null}"/>
</StackPanel>

DataBinding the Enabled property of a control to a string field

I've got a C#.NET project using strongly-typed DataSets and TableAdapters and such, and I have UserControls dedicated to handling the editing of records via BindingSource.
I'm wondering if it's at all possible for me to bind the Enabled property of a TextBox to dynamically enable or disable it based on the contents of another [string] field in the current record of a BindingSource, e.g. if the field contains a word or is a certain value, or if I should resort to just good old event handling?
Some code to (hopefully) illustrate what I'm attempting:
//An instance of a custom StronglyTypedDataSet "ds" already exists
//with a table called "table" defined in it with at least one record.
BindingSource bs = new BindingSource(ds, "table");
bs.Position = 0;
//A TextBox txtField2 exists on the form.
//txtField2.Text is bound to the value of ds.table.Field2, and I want it to enable
//itself if the contents of ds.table.Field1 meet certain criteria.
txtField2.DataBindings.Add("Text", bs, "Field2");
txtField2.DataBindings.Add("Enabled", bs, "Field1", true, DataSourceUpdateMode.Never,
false, "WHAT GOES HERE?");
Absolutely. While I find a lot of the specifics incredibly complicated much of the time, one of the beautiful things about WPF is that you can pretty much bind anything to anything else, as long as you have a clear idea of what that binding would mean.
In your case, it seems you want to take as input a string value (i.e. the value of the TextBox.Text property), and bind it to a bool property based on some known criteria.
Here is an example of how you might do that. First, you need to write the shim that converts from the string to the bool. For example:
class StringToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string text = value as string;
if (text != null)
{
string matchText = (string)parameter;
return text == matchText;
}
return Binding.DoNothing;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Note that here, I allow the binding to pass a parameter, and do a simple equality comparison. But you are free to do anything here you want, as long as you take the string input and return a bool value. You can hard-code the entire logic in the converter itself, or you can come up with a way to represent your criteria as a parameter and pass it to the converter that way (or of course make use of some state elsewhere in the program, but IMHO it makes more sense to pass the criteria as a parameter if you want to customize it).
With the converter done, it's trivial to then configure the binding so that it uses that. For example:
<Window x:Class="TestSO28075399ConvertStringToBoolean.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestSO28075399ConvertStringToBoolean"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<StackPanel.Resources>
<local:StringToBooleanConverter x:Key="stringToBooleanConverter1" />
</StackPanel.Resources>
<Border BorderBrush="Black" BorderThickness="1">
<TextBox x:Name="textBox1" />
</Border>
<Button Content="Click me!" Width="100" HorizontalAlignment="Left"
IsEnabled="{Binding ElementName=textBox1,
Path=Text,
Converter={StaticResource stringToBooleanConverter1},
ConverterParameter=Hello}" />
</StackPanel>
</Window>
When declaring it as a resource, the converter object can be anywhere in the resource chain. It doesn't have to be in the StackPanel itself.
With the above code, the "Click me!" button will be enabled only if the user types exactly the text "Hello" into the TextBox.
If this has to be set up dynamically in a way that isn't supported via XAML, you can of course do all of the above programmatically as well. Just translate the relevant XAML to its equivalent in C# code.

Bind textblock to dictionary value for key in XAML?

I have a model with an enum property (in this case, related to Export Control Regulations). When displaying the value to the user, I want to show a corresponding string. Sometimes this is in ComboBox (where the user can select a value), and sometimes it is in a TextBlock (where it is read-only).
Example: for ExportRegulationType.EAR, I want to display "EAR", while for ExportRegulationType.DoNotExport, I want to display "Do Not Export". Note that I don't have any language localization needs, but I recognize the issue...
Currently, in my ViewModel, I have a property that returns a string based on the current enum value, and also another property that returns a Dictionary<ExportRegulationType, string>. For the ComboBoxes, I can bind ItemsSource to the dictionary property, and for the TextBlocks, I can bind to the string property. This works, but is kind of clumsy.
Two questions:
1) It seems to me that I should be able to declare the dictionary (with keys and values) as a static resource in XAML (probably in App.xaml), and use that for the ItemsSource for the ComboBox version. However, I can't figure out how to declare and reference such a thing. How can I do that?
2) Assuming the above is in place, I would think I could also set up a binding with the textblock, so based on the enum property, it will look up the string in the dictionary.
I have seen the following questions relating to a static or dynamic enum value. The first isn't adequate, and the second isn't answered...
These should be a XAML-only, and will enable me to remove the methods from my ViewModel (having only the one exposed ExportRegulationType enumerated property. Are these possible?
Edit: Additional information:
In the application, I will have many different sets of views, models, and ViewModels. However, as export control regulations are a common and consistent requirement, I am using composition to keep it DRY. i.e., Models A and B both have an ExportControl model. ViewModels A1, A2, B1 and B2 will have an ExportControlViewModel. The views will have controls bound to the ExportControlViewModel of their ViewModel. The views will have either a ComboBox or a TextBlock, but not both (Depending on if the user can change the value).
I don't know if this will work for your case, but here is a possible solution. In your view model, expose a ExportRegulationType property and then create a value converter to display your desired string.
First create your value converter:
class ExportRegulationTypeToStringConverter: IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ExportRegulationType regType = (ExportRegulationType)value;
switch(regType)
{
case ExportRegulationType.EAR:
return "EAR";
case ExportRegulationType.DoNotExport:
return "Do Not Export";
//handle other cases
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Binding.DoNothing;
}
#endregion
}
Then add a reference to your converter in your xaml. local is the namespace in which your class is located.
<local:ExportRegulationTypeToStringConverter x:Key="exportRegConverter" />
Finally, set the value of your text box to use the converter. pathToEnum is the property exposed on your ViewModel of type ExportRegulationType.
<TextBlock Text="{Binding pathToEnum, Converter={StaticResource exportRegConverter}}" />
Use ObjectDataProvider to fill the ComboBox with the values of the enum.
<Window.Resources>
<ObjectDataProvider x:Key="dataFromEnum"
MethodName="GetValues" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:ExportRegulationType"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
Now we create the ComboBox and use a container style with our value converter to display the desired strings for our enum.
<ComboBox ItemsSource="{Binding Source={StaticResource dataFromEnum}}">
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem">
<Setter Property="Content" Value="{Binding Converter={StaticResource exportRegConverter}}" />
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
Instead of the Dictionary you have another option.
See the following question: WPF Binding a ListBox to an enum, displaying the Description Attribute
You could add a Description Attribute to your enums like this
public enum ExportRegulationType
{
[Description("EAR")]
EAR,
[Description("Do Not Export")]
DoNotExport
}
And when you want to display it, you can just use EnumDescriptionConverter Converter found in the question I linked
I solved this with a blend of what #Dylan and #Meleak wrote. I'm putting this as an answer to show what the final solution was:
First, I implemented an IValueConverter, (based on #Meleak's answer):
class EnumDescriptionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Enum regulation = (Enum)value;
return GetEnumDescription(regulation);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return String.Empty;
}
/// <summary>
/// Returns text intended for display based on the Description Attribute of the enumeration value.
/// If no Description Attribute is applied, the value is converted to a string and returned.
/// </summary>
/// <param name="enumObj">The enumeration value to be converted.</param>
/// <returns>Text of the Description Attribute or the Enumeration itself converted to string.</returns>
private string GetEnumDescription(Enum enumObj)
{
// Get the DescriptionAttribute of the enum value.
FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
object[] attributeArray = fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributeArray.Length == 0)
{
// If no Description Attribute was found, default to enum value conversion.
return enumObj.ToString();
}
else
{
// Get the text of the Description Attribute
DescriptionAttribute attrib = attributeArray[0] as DescriptionAttribute;
return attrib.Description;
}
}
}
I tagged my enum (note that several values are not tagged as the desired text is the same as the value itself):
public enum ExportRegulationType
{
[Description("Not Determined")]
NotDetermined, // Export authority not determined
EAR, // Controlled by EAR Regulations
ITAR, // Controlled by ITAR Regulations
[Description("Do Not Export")]
DoNotExport, // Export not allowed
Unrestricted // Export not controlled
}
In my App.xaml, I declared the ObjectDataProvider to get the list of enum values and the EnumDisplayConverter (Here since they will be used by several different views):
<Application.Resources>
[Other stuff...]
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="ExportRegulationValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="models:ExportRegulationType"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<local:EnumDescriptionConverter x:Key="ExportDisplayConverter"/>
</Application.Resources>
For a TextBlock:
<TextBlock Text="{Binding Export.Regulation, Converter={StaticResource ExportDisplayConverter}}"/>
For a Combo Box:
<ComboBox ItemsSource="{Binding Source={StaticResource ExportRegulationValues}}"
SelectedValue="{Binding Document.Export.Regulation}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource ExportDisplayConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
This works perfectly!
Use an ObjectDataProvider
then bind the ComboBox's Items to it, and set "DisplayMemberPath" to "Value".
What this should do is to show the values of your dictionary, but in code-behind the SelectedValue is a KeyValuePair<>.
For your textblock, use a Binding using ElementName=yourcombobox and Path=SelectedItem:
<TextBlock Text="{Binding SelectedItem, ElementName=yourcombobox}" />
Let me know how it goes =)
Here is a blog post of mine with an approach using attached behaviors.
It is based on the principle that different enumeration values don't need to be limited to switching strings. Instead, you can declare whatever pieces of UI you want to represent each value (strings, images, different controls and layouts, etc.) and use an attached behavior to control their visibility.
Your situation, then, can be framed as having two different text blocks, each bound to the same property of type ExportRegulationType. Since they are bound to the same property, their visibilities are mutually exclusive:
<Grid>
<TextBlock
Text="EAR"
local:EnumVisibility.Value="{Binding ExportRegulationType}"
local:EnumVisibility.TargetValue="EAR"
/>
<TextBlock
Text="Do Not Export"
local:EnumVisibility.Value="{Binding ExportRegulationType}"
local:EnumVisibility.TargetValue="DoNotExport"
FontWeight="Bold"
/>
</Grid>
I included the FontWeight="Bold" to show that you can make different decisions for each enumeration value. This also supports XAML localization because the text is set like any other text block.
See the post for a complete walkthrough of the solution, code samples, and a zip file containing the framework and an example application.
Edit in response to additional information:
Here is another post in the same series which describes how to select enumeration values with Selector controls.
A ComboBox bound to the ExportRegulationType property would look this this:
<ComboBox local:EnumSelector.SelectedValue="{Binding ExportRegulationType, Mode=TwoWay}">
<ComboBoxItem Content="EAR" local:EnumSelector.ItemValue="EAR" />
<ComboBoxItem Content="Do Not Export" local:EnumSelector.ItemValue="DoNotExport" />
</ComboBox>
We associate each item with an enumeration value, then use a TwoWay binding to EnumSelector.SelectedValue so it will write back to the view model's property whenever it changes.
This provides the same flexibility as with the text blocks: you can make whatever decisions you want about how to set the text and what is contained by each item.

Categories

Resources