Best Approach of setting the Visibility in MVVM - wpf

In my View I have three objects, of which one is Visible at any given time. In my Model I have an enumeration to represent the three states.
How should I implement my ViewModel?
a) Create a boolean for the visibility of each object, and bind each object to this (with a bool->visibility converter).
b) Bind to the enum, with a unique converter for each object.
c) Bind to the enum, with a single converter that takes a parameter.
d) Use a visual state manager with boolean key frames, and drive the state from VM with an attached property.
e) Bind to the VM enum from code behind, and set visibility thru code.
f) ?
I am seriously hoping the answer is f) (ie the obvious choice that escapes me), because I am not really overjoyed with a) through e).
Thoughts welcome and appreciated.

The Best approach in MVVM does not necessarily mean easy. I like the following approaches:
a) Create a boolean for the visibility of each object, and bind each object to this (with a bool->visibility converter).
This method is the most intuitive and classically for setting Visibility for Control.
b) Bind to the enum, with a unique converter for each object.
c) Bind to the enum, with a single converter that takes a parameter.
In the case of the Converter, Enum is the best keep not in the Model and in the side of View. Because the problem solves over to the side of View, which is quite logical and here to store the data structure. In principle, it is not critical.
Example:
public sealed class InvertableBooleanToVisibilityConverter : IValueConverter
{
enum Parameters
{
Normal,
Inverted
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var boolValue = (bool)value;
var direction = (Parameters)Enum.Parse(typeof(Parameters), (string)parameter);
if (direction == Parameters.Inverted)
return !boolValue ? Visibility.Visible : Visibility.Collapsed;
return boolValue ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}
A couple of comments about other approaches:
d) Use a visual state manager with boolean key frames, and drive the state from VM with an attached property.
For these situations, it looks complicated, so do not see the point in it. But, if the conditions of setting Visibility are not difficult, you can use VisualStateManager.
e) Bind to the VM enum from code behind, and set visibility thru code.
Code-behind in this case is not justified when you can solve the problem using typical tools of MVVM (Binding, Converters, etc). I think, in this case it would not be a violation of the principle of MVVM, if choosing the element to the Visibility is not involved business logic, such as may come setting Visibility by pressing of CheckBox, ToggleButton, etc.

c) Bind to the enum, with a single converter that takes a parameter.
This way I solved my problem with radio buttons where only one of the radio buttons is selected. Seem harder but you can reuse it later and if you get the idea it is very easy.
e) Bind to the VM enum from code behind, and set visibility thru code.
Bad idea. That's not a good practice.

in addition to my comment. when i have the task to show diffenrent content in a view depending on different objects. i use most time a contentcontrol and datatemplates.
<ContentControl Content="{Binding MyEnumObject}"/>
now in my viewmodel i have all the diffrent objects types and set the object i want to my Property bind to the view.
private Blup _blup; //eg. is wanted when enum in model = 1
public object MyEnumObject {get;set;}
//set the content in your viewmodel
this.MyEnumObject = _blup;
now you just need a datatemplate to visualize your objects
<DataTemplate DataType="{x:Type local:Blup}">
<view:MyBlupViewControl/>
</DataTemplate>
but maybe i m totally wrong. but your actuall question let so much room for interpretation

Related

WPF / MVVM Design Suggestions

I'm pretty new to WPF, and am looking for some guidance here.
I'm working on an application that will be used to print out work orders for our fulfillment department.
Right now I have 2 windows: The first is the main screen, the second is a window with a gridview that will hold the work orders to print.
The first page will have several buttons on there. Every button will open up the second window; however, depending on which button is clicked, the parameters passed into the service that will load data will be different.
What would be the best practices way of doing this?
Is there way to define these parameters somewhere on the Button control, and then pass them through via ICommand/RelayCommand?
Should I create a UserControl/ServerControl that will let me build in these additional properties?
Something else I'm not thinking of?
Edit:
To give a rough example (and this is very oversimplified}, say i have 2 sets of criteria: OrderTypes: {Rush, Today, Future} and Locations {Warehouse 1, Warehouse 2, Warehouse 3}
The main window would have a 3x3 grid of buttons, one for each combination. I'd like to be able to specify on a single button "Expedite & Warehouse 1"; and then pass those parameters back to a single method, which would open the second window.
Lets say you have MainWindow and buttons are placed in it.
Create a MainWindowViewModel and set it as DataContext for MainWindow.
Have an ICommand on your ViewModel and bind button Command with this ICommand so that entry point for opening another window will be single. For ICommand you can use either RelayCommand or DelegateCommand whichever suits you best.
Now, comes the point where you need to open window and pass on parameter to it based on button type click. I would suggest to have Enum depicting action need to perform based on different buttons.
Enum
public enum ActionType
{
Action1,
Action2,
Action3 and so on...
}
And bind from button like this:
<Button Command="{Binding CommandInstance}"
CommandParameter="{x:Type local:ActionType.Action1}"/>
<Button Command="{Binding CommandInstance}"
CommandParameter="{x:Type local:ActionType.Action2}"/>
where local will be namespace where enum is declare.
And in command execute delegate pass the enum value to another window constructor:
private void CommandMethod(ActionType action)
{
AnotherWindow anotherWindow = new AnotherWindow(action);
anotherWindow.Show();
}
and from action passed in constructor, you can check what parameter need to pass to service responsible for loading data.
Also, in case creating window from ViewModel doesn't seems right you can have Service wrapper over window Controls which is responsible for showing/closing window.
UPDATE
Since you want to pass multiple parameters from Views so maintaining enum for this will be cumbersome. You can pass multiple values from View using IMultiValueConverter.
Let me explain with small example:
<Button Command="{Binding TestCommand}">
<Button.Resources>
<sys:String x:Key="Rush">Rush</sys:String>
<sys:String x:Key="Warehouse">Warehouse</sys:String>
</Button.Resources>
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource MultiValuesReturnConverter}">
<Binding Source="{StaticResource Rush}"/>
<Binding Source="{StaticResource Warehouse}"/>
</MultiBinding>
</Button.CommandParameter>
</Button>
where sys will be namespace for System in XAML:
xmlns:sys="clr-namespace:System;assembly=mscorlib"
So, now you have liberty in XAML to pass many objects from XAML to your command parameter. All you have to do is to declare the resource under Button resources section and pass it as binding to converter.
Converter code to convert it into list of parameters which can be passed to command as a single parameter object:
public class MultiValuesReturnConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType,
object parameter, CultureInfo culture)
{
return values.ToList<object>();
}
public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, CultureInfo culture)
{
throw new System.NotImplementedException();
}
}
Command Method:
private void CommandMethod(object parameter)
{
// Now you have all the parameters here to take decision.
IList<object> values = parameter as List<object>;
AnotherWindow anotherWindow = new AnotherWindow(action);
anotherWindow.Show();
}
If you don't want to use some third party library, there really is no problem in simply passing the parameters through a click event into your other window's constructor. If your data is represented by a viewmodel you may also pass that viewmodel instead of the parameters themselves.
A point of MVVM is not "no code-behind". Many times you will end up without code-behind, but trying to develop applications this way leads you into convoluted anti-patterns that often are more work and more lines of code than simple click events and "the old way".
Treat your data as data, try to do all your work in testable viewmodels and never follow a pattern too rigidly lest you end up with mounds of unreadable abstractions.
Before detailing any thing, I would advice you to use the third party library MVVMLight, it has many helpful features such as Messenger, its own RelayCommands etc ...
For passing parameters from a button to consume them in Commands, you can use the Tag property if you want to pass a parameter regardless of the type of the event, if you want to pass a parameter that is related to a certain Command(event) then CommandParameter is what you need :
Tag : Gets or sets an arbitrary object value that can be used to store custom information about this element. (Inherited from FrameworkElement.)
CommandParameter :
<Button Content="Parameterized Command"
Command="{Binding ParameterizedCommand}" CommandParameter={Binding SomeObject} />
I don't think at the level of your question that you need to create a UserControl unless you have more complicated scenarios.
You can use the Messenger class to pass information from ViewModel to another (this just a helper it's independent from the MVVM Pattern).
The MVVMLight has code templates that help you create ViewModels with ease.
The MVVMLight has many helpful snippets which you will find helpful.
Beware of Commands because they are not originally supported with all UIElements, they are only available with ButtonBase and its children and they work only to replace the Click event, to use Commands and CommandParameters with other UIElements and with other kinds of events you should use a sort of EventToCommand behaviours, MVVMLight has got that already ready for you
Hope I covered most important parts you may need.
The most easy and intuitive way (Using INotifyPropertyChanged to update the UI instead of DependencyProperty):
You create a property that'll be your DataContext for your OrderViewModel in MainWindowViewModel
class MainWindowViewModel : ViewModelBase // ViewModelBase should implement INotifyPropertychanged, unless you're using dependency properties
{
private OrderViewModel _OrderViewModelInstance;
public OrderViewModel OrderViewModelInstance
{
get{ return _OrderViewModel;}
set { _OrderViewModel = value;
OnPropertyChanged("OrderViewModel")} // Method from ViewModelBase
}
Now, whichever way You're creating Your Order View:
You instantiate OrderViewModel in MainWindowViewModel (Let's say when a button gets clicked) with desired parameters.
you bind the Order view's DataContext to OrderViewModelInstance in XAML. You might want to create an additional variable that tells you when the window is visible.

Pass view to viewmodel with datatemplate

I have a window named ParameterEditorView with a ParameterEditorViewModel as DataContext. In the ParameterEditorViewModel I have a list of ParameterViewModel. In the ParameterEditorView I have an ItemsControl whose ItemsSource is binded to the list of ParameterViewModel in the ParameterEditorViewModel. I need the ParameterViewModel to have a reference to the ParameterView (more on that later). In the Resources section of the ParameterEditorView I add the DataTemplate:
<DataTemplate DataType="{x:Type my:ParameterViewModel}" >
<my:ParameterView HorizontalAlignment="Left"/>
</DataTemplate>
So, how can I pass a reference of the ParameterView that is created to show the ParameterViewModel to it?
The reason I need the ParameterView in the ParameterViewModel is the following:
I have a TextBox whose Text property is binded to the PropertyModelView.Name property. But I want to display a default string when the Name is empty or Null. I've tried to set the property value to the default string I want when that happens but the TextBox.Text is not set in this scenario. I do something like this:
private string _name;
public string Name
{
get { return _name; }
set
{
if (value == null || value.Length == 0)
Name = _defaultName;
else
_name = value;
}
}
I've also tried to specifically set the TextBox.Text binding mode to TwoWay without success.
I think this is a defense mechanism to prevent an infinite loop from happening but I don't know for sure.
Any help on this front would also be highly appreciated.
Thanks,
José Tavares
{Binding } has a FallbackValue, btw.
Your question, it confuses me. I'd assume your PVM has a collection of PV's as a public property, which is bound within the UI. Also, I think you're mixing terms. Its Model-View-ViewModel where the ViewModel is the DataContext of the View, and the Model is exposed by the ViewModel via a public property. Sounds like if you're binding the window to a collection of ViewModels they are actually Models. It may seem pedantic, but getting your terms correct will help you research and ask questions.
Another solution would be to add a Converter to your Binding in combination with FallbackValue (I've had to do this, IIRC). That converter would be an IValueConverter that returns "DependencyProperty.UnsetValue" if the string is null or empty. I think this works sometimes because the TextBox will set the bound property to the empty string rather than null if the TB is empty. Here's a little sample to whet your whistle (not guaranteed to work; you need to debug this and tweak it):
public class ThisMightWorkConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
var temp = value as string;
if(string.IsNullOrWhiteSpace(temp))
return System.Windows.DependencyProperty.UnsetValue;
return temp;
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
return value; // you might need to change this
}
}

WPF+MVVM: How to display VM via resource dictionary

At the moment I am creating new instance of both View and ViewModel and assign view.DataContext = vm in the application in the handler of 'Startup' application event
In the http://msdn.microsoft.com/en-us/magazine/dd419663.aspx in the "Applying a View to a ViewModel" chapter I've read that it would be a good idea to bind ViewModel object to view via resources.
Am I correctly understand that using suggested approach I should:
Create a resource in the "MainPage" that will have a "DataTemplate" section for each pair of View/ViewModel;
Bind instance of the ViewModel object to the MainPage?
Am I right?
P.S. Actually, I've tried to do that but got few issues and want to know if I am going by the proper way. If no, please point me how that should be done in the right way.
How this technique works is that instead of finding and creating views directly let wpf find the view through data templates. so when you have the following in your application resources. This drives the UI based on what ViewModel you want to display and don't have to worry about coding up the view.
<DataTemplate DataType="{x:Type vm:MyViewModel}">
<ui:MyView />
</DataTemplate>
Note: vm: and ui: are just xml namespaces declared in the top element of the resource file.
you can then just create a generic window that will 'find' the view via a ContentControl
<Window ...>
<ContentControl Content="{Binding}" />
</Window>
var window = new Window();
window.DataContext = new MyViewModel();
window.Show();
This will display the window embedding MyView as the content of the window. Provided you have your bindings set in your view pointing to properties in your viewmodel the wire up succeed. No need to 'new' up a view. The main window can be reused simply by reassigning a different view model to the data context.
Also if you let us know what specific issues you are having we will be able to provide a more specific answer if the above is not what you are looking for.
HTH
I used to do a key/value pair for all of my ViewModel/View like aqwert suggests, but once you get a couple dozen,or more than one :), ViewModels it starts getting pretty tedious and prone to typos.
I personally like an IValueConverter doing the work for me and using Convention for the location of the View.
For example let's say I have my view models in namespace MyApp.ViewModels
and all of my Views in namespace MyApp.Views
and I have a suffix of ViewModel behind all of my VMs and a suffix of View behind all of my Views
All I have to do is:
1) Have all of my ViewModels inherit from a base class ViewModelBase
2) Put this in my application resource dictionary
<m:ViewModelConverter x:Key="ViewModelConverter"/>
<DataTemplate DataType="{x:Type vm:ViewModelBase}">
<ContentControl Content="{Binding Converter={StaticResource ViewModelConverter}}"/>
</DataTemplate>
3) Create my converter, the following is just an example, you can modify to meet your convention.
public class ViewModelConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
Type ViewModelType = value.GetType();
string ViewNameSpace = ViewModelType.Namespace.Replace("ViewModel", "View");
string ClassName = ViewModelType.Name.Replace("Model", string.Empty);
Type ViewType = Type.GetType(string.Format("{0}.{1}", ViewNameSpace, ClassName));
if (ViewType != null)
return Activator.CreateInstance(ViewType);
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
#endregion
}
The above will try and find the view, if it doesn't it will just return the ViewModel that it was trying to convert (which WPF will just call .ToString() on)
You don't have to worry about actual wiring of ViewModel to the View's DataContext because WPF does that automatically.
And then I'm done. I don't have to touch my resource file any more. :)

WPF Property Data binding to negate the property

Is there any way to change the value of property at runtime in WPF data binding. Let's say my TextBox is bind to a IsAdmin property. Is there anyway I can change that property value in XAML to be !IsAdmin.
I just want to negate the property so Valueconverter might be an overkill!
NOTE: Without using ValueConverter
You can use an IValueConverter.
[ValueConversion(typeof(bool), typeof(bool))]
public class InvertBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool original = (bool)value;
return !original;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
bool original = (bool)value;
return !original;
}
}
Then you'd setup your binding like:
<TextBlock Text="{Binding Path=IsAdmin, Converter={StaticResource boolConvert}}" />
Add a resource (usually in your UserControl/Window) like so:
<local:InvertBooleanConverter x:Key="boolConvert"/>
Edit in response to comment:
If you want to avoid a value converter for some reason (although I feel that it's the most appropriate place), you can do the conversion directly in your ViewModel. Just add a property like:
public bool IsRegularUser
{
get { return !this.IsAdmin; }
}
If you do this, however, make sure your IsAdmin property setter also raises a PropertyChanged event for "IsRegularUser" as well as "IsAdmin", so the UI updates accordingly.
If you specifically want to do this at XAML end (I am not sure the reason for that, unless you have 100s of similar operation of negate) there are only two ways 1) Using IValueConverter 2)write a XAML Markup Extension (Way too much work for this small task :))
Then the other obvious way is to write another property in your ViewModel , which can return the Negative of the IsAdmin property.
You can't bind to !Property, but you could create a new Binding with an appropriate IValueConverter and change out the entire Binding at runtime. The key is the BindingOperations class, which allows you to change the binding on a particular DependencyProperty.
public static void InvertBinding(DependencyObject target, DependencyProperty dp)
{
//We'll invert the existing binding, so need to find it
var binding = BindingOperations.GetBinding(target, dp);
if (binding != null)
{
if (binding.Converter != null)
throw new InvalidOperationException("This binding already has a converter and cannot be inverted");
binding.Converter = new InvertingValueConverter(); //This would be your custom converter
//Not sure if you need this step, but it will cause the binding to refresh
BindingOperations.SetBinding(target, dp, binding);
}
}
This should give you a general idea; I wouldn't use this for production code, as you'd probably want to generalize it to toggle the converter or whatever else you need to change out at runtime. You could also avoid changing the binding entirely by creating a new property you bind to that encapsulates this 'switching' logic. The last option is probably the best.
You can write a ValueConverter that automatically negates the input before returning it. Have a look at BenCon's blog for a short reading on value converters.

Why would putting a no-op Converter on a Binding change its behavior?

I'm in the midst of testing a user control I've built, and I'm encountering something that's inexplicable to me.
The control's an extension of the ComboBox that handles values of a specific custom type. It has a dependency property of that custom type that is the target property of a Binding.
I've got a trace statement in the setter, and I can see that the property is getting set. But it's not appearing in my user control.
Now, ordinarily I'd say, okay, I've got a bug in my user control. I probably do, though I'm baffled about it. But this question isn't about finding the bug in my control. Read on; here is where it gets weird.
I'm also using Bea Stollnitz's little value converter to help debug the Binding:
public class DebuggingConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value; // Add the breakpoint here!!
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException("This method should never be called");
}
}
The idea behind this is that I add this converter to my Binding and can set a breakpoint to see what value is being pushed out to the target. Okay, that works just fine. I can see that the value is being pushed out.
In fact, it works a little too fine. If the DebuggingConverter is attached to the Binding, the user control displays the value. If it's not, it doesn't.
How is that even possible? How could a value converter that does nothing affect the behavior of a bound control?
Edit:
Not that it's likely to help, but here's the XAML for the user control:
<a:CodeLookupBox
Grid.Column="1"
Grid.IsSharedSizeScope="True"
MinWidth="100"
Style="{Binding Style}">
<a:CodeLookupBox.CodeLookupTable>
<Binding Path="Codes" Mode="OneWay"/>
</a:CodeLookupBox.CodeLookupTable>
<a:CodeLookupBox.SelectedCode>
<Binding Path="Value" Mode="TwoWay" ValidatesOnDataErrors="True"/>
</a:CodeLookupBox.SelectedCode>
</a:CodeLookupBox>
Without the converter on the second binding, the control behaves as though I didn't set SelectedCode. Even though a trace statement in the OnSelectedCodePropertyChanged handler shows that e.Value does indeed contain the correct value. This happens irrespective of whether the converter's attached or not.
I've been trying to reverse-engineer this problem with a thought experiment: if you wanted to create a bound user control whose behavior changed if a no-op converter were attached to its binding, how would you do it? I don't know enough about binding to come up with an answer.
Well, the good news is, I know why SelectedCode isn't being set when I'm not using a value converter. The bad news is, I still have something of a mystery, but the problem's been pushed up the food chain a bit, and I have a workaround.
This control is essentially a strongly-typed combo box with a bunch of additional features that are made possible by the fact that it knows what kind of items are in it. The SelectedCode and CodeLookupTable properties are strongly typed, and they hide the underlying SelectedItem and ItemsSource properties, which aren't. (This, by the way, is why this is a user control and not a subclass of ComboBox; I don't want those properties to be visible because a lot of things can happen if they get set improperly, none of them good.)
Here's what's happening. This is my debugging output when the value converter is attached (the number is the hash code of the control, because I've got a bunch of them that all get drawn simultaneously when the program's initialized):
14626603: OnCodeLookupTablePropertyChanged
CodeLookupTable property set to Proceedings.Model.CodeLookupTable
box.MainComboBox.ItemsSource = MS.Internal.Data.EnumerableCollectionView
14626603: OnSelectedCodePropertyChanged:
SelectedCode property set to Unlicensed Driver [VC12500(A)]
box.MainComboBox.ItemsSource = MS.Internal.Data.EnumerableCollectionView
This is the expected behavior. The CodeLookupTable property is set, so setting SelectedCode to one of the items in that collection correctly sets SelectedItem on the underlying ComboBox.
But without the value converter, we get this:
16143157: OnSelectedCodePropertyChanged:
SelectedCode property set to Unlicensed Driver [VC12500(A)]
box.MainComboBox.ItemsSource =
16143157: OnCodeLookupTablePropertyChanged
CodeLookupTable property set to Proceedings.Model.CodeLookupTable
box.MainComboBox.ItemsSource = MS.Internal.Data.EnumerableCollectionView
Here, the SelectedCode property is being set before the CodeLookupTable property is. So when the method tries to set SelectedItem on the underlying ComboBox, nothing happens, because the ItemsSource is null.
And here is the root of the problem. I've foolishly assumed that the order that bindings update their target in is the same as the order they're declared in the XAML. (One of the reasons I've expressed the bindings as elements instead of attributes is because the order of elements in an XML document is deterministic and the order of attributes isn't. It's not like I didn't think about this.) This is apparently not the case.
I've also assumed, maybe a little less foolishly, that the order in which bindings update their target isn't dependent on whether or not they have attached value converters. Well, it is. I wonder what else it depends on.
Mercifully, I have a way to work around this. Since my CodeLookup object contains a reference to the CodeLookupTable, I can make the SelectedCode setter set the CodeLookupTable (and thus the ItemsSource) property first, if it hasn't already been set. That'll make this problem go away without having to stick a fake value converter on the binding and hope that the way bindings behave never changes.
Edit
Here's what the property declarations look like:
#region SelectedCode
public static readonly DependencyProperty SelectedCodeProperty = DependencyProperty.Register(
"SelectedCode", typeof(CodeLookup), typeof(CodeLookupBox),
new FrameworkPropertyMetadata(OnSelectedCodePropertyChanged));
private static void OnSelectedCodePropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
CodeLookupBox box = (CodeLookupBox)source;
CodeLookup code = e.NewValue as CodeLookup;
// this right here is the fix to the original problem:
if (box.CodeLookupTable == null && code != null)
{
box.CodeLookupTable = code.Table;
}
box.MainComboBox.SelectedItem = e.NewValue;
}
public CodeLookup SelectedCode
{
get { return GetValue(SelectedCodeProperty) as CodeLookup; }
set { SetValue(SelectedCodeProperty, value); }
}
#endregion
#region CodeLookupTable
public static readonly DependencyProperty CodeLookupTableProperty = DependencyProperty.Register(
"CodeLookupTable", typeof(CodeLookupTable), typeof(CodeLookupBox),
new FrameworkPropertyMetadata(OnCodeLookupTablePropertyChanged));
private static void OnCodeLookupTablePropertyChanged(DependencyObject source,
DependencyPropertyChangedEventArgs e)
{
CodeLookupBox box = (CodeLookupBox)source;
CodeLookupTable table = (CodeLookupTable)e.NewValue;
box.ViewSource = new CollectionViewSource { Source = table.Codes };
box.View = box.ViewSource.View;
box.MainComboBox.ItemsSource = box.View;
}
public CodeLookupTable CodeLookupTable
{
get { return GetValue(CodeLookupTableProperty) as CodeLookupTable; }
set { SetValue(CodeLookupTableProperty, value); }
}
#endregion
try to implement the ConvertBack function too, you are using two-way binding so the problem may be that the exception will be ignored by the "xaml" but when you step in debug mode you maybe stop the "send value back"-operation?
Hmm...very strange. I've seen similar behavior when dealing with MultiBindings with multiple converters, but not on a simple binding. Out of curiosity, how are you defining your DPs on the control? (including the callbacks, metadata options, etc)
Some stuff to try (after removing the converter hook):
Default the mode (ie, remove the TwoWay)
Remove the ValidatesOnDataErrors
Add an AffectsRender to the SelectedCode DP
What does setting SelectedCode do? Can you post the code for the property changed handler?
You've suggested that debugging shows the property is being set to the correct value, so the most obvious suggestion is that the code providing your intended behaviour is incorrect.

Resources