MarkupExtension that uses a DataBinding value - wpf

I'm trying to create a WPF MarkupExtension class that provides translated text from my text translation class. The translation stuff works great, but requires a static method call with a text key to return the translated text. Like this:
ImportLabel.Text = Translator.Translate("import files");
// will be "Dateien importieren" in de or "Import files" in en
Its speciality is that it accepts a counting value to provide better wordings.
ImportLabel.Text = Translator.Translate("import n files", FileCount);
// will be "Import 7 files" or "Import 1 file"
Another example: If something takes yet 4 minutes, it's a different word than if it only takes one minute. If a text key "minutes" is defined as "Minuten" for any number and as "Minute" for a count of 1, the following method call will return the right word to use:
Translator.Translate("minutes", numberOfMinutes)
// will be "minute" if it's 1, and "minutes" for anything else
Now in a WPF application, there's a lot of XAML code and that contains lots of literal texts. To be able to translate them without getting nuts, I need a markup extension which I can pass my text key and that will return the translated text at runtime. This part is fairly easy. Create a class inheriting from MarkupExtension, add a constructor that accepts the text key as argument, store it in a private field, and let its ProvideValue method return a translation text for the stored key.
My real problem is this: How can I make my markup extension accept a counting value in such a way that it's data-bound and the translation text will update accordingly when the count value changes?
It should be used like this:
<TextBlock Text="{t:Translate 'import files', {Binding FileCount}}"/>
Whenever the binding value of FileCount changes, the TextBlock must receive a new text value to reflect the change and still provide a good wording.
I've found a similar-looking solution over there: http://blogs.microsoft.co.il/blogs/tomershamam/archive/2007/10/30/wpf-localization-on-the-fly-language-selection.aspx But as hard as I try to follow it, I can't understand what it does or why it even works. Everything seems to happen inside of WPF, the provided code only pushes it in the right direction but it's unclear how. I can't get my adaption of it to do anything useful.
I'm not sure whether it could be useful to let the translation language change at runtime. I think I'd need another level of bindings for that. To keep complexity low, I would not seek to do that until the basic version works.
At the moment there's no code I could show you. It's simply in a terrible state and the only thing it does is throwing exceptions, or not translating anything. Any simple examples are very welcome (if such thing exists in this case).

Nevermind, I finally found out how the referenced code works and could come up with a solution. Here's just a short explanation for the record.
<TextBlock Text="{t:Translate 'import files', {Binding FileCount}}"/>
This requires a class TranslateExtension, inherited from MarkupExtension, with a constructor accepting two parameters, one String and one Binding. Store both values in the instance. The classes' ProvideValue method then uses the binding it gets, adds a custom converter instance to it and returns the result from binding.ProvideValue, which is a BindingExpression instance IIRC.
public class TranslateExtension : MarkupExtension
{
public TranslateExtension(string key, Binding countBinding)
{
// Save arguments to properties
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
countBinding.Converter = new TranslateConverter(key);
return countBinding.ProvideValue(serviceProvider);
}
}
The converter, say of class TranslateConverter, has a constructor that accepts one parameter, a String. This is my key argument from the TranslateExtension above. It remembers it for later.
Whenever the Count value changes (it comes through the binding), WPF will request its value anew. It seems to walk from the source of the binding, through the converter, to the surface where it's displayed. By using a converter, we don't have to worry about the binding at all, because the converter gets the binding's current value as a method argument and is expected to return something else. Counting value (int) in, translated text (string) out. This is my code.
So it's the converter's task to adapt the number to a formulated text. It uses the stored text key for that. So what happens is basically a kinda backwards data flow. Instead of the text key being the main information and the count value being added to it, we need to treat the count value as the primary information and just use the text key as a side parameter to make it whole. This isn't exactly straightforward, but the binding needs to be the primary trigger. Since the key won't change, it can be stored for good in the instance of the converter. And every occurence of a translated text gets its own copy of the converter, each with an individual key programmed in.
This is what the converter could look like:
class TranslateConverter : IValueConverter
{
private string key;
public TranslateConverter(string key)
{
this.key = key;
}
public object Convert(object value, ...)
{
return Translator.Translate(key, (int) value);
}
}
That's the magic. Add the error handling and more features to get the solution.

Related

Winforms ObjectListView: inner OLVColumn instances Name property is empty string so I cannot show/hide columns by name

This question is an offshoot of: Localizing ObjectListView OLVColumn, impossible due to Empty Name property
For simplicity's sake, let's say my ObjectListView contains car information. User A wants to display only Make and Model columns. User B only wants to display Model and Year columns. These preferences would be saved to/loaded from an .ini file on the users' local machines.
I cannot loop through the columns of the ObjectListView and do if (col.Name == colNameFromIni) { col.Visible == true; } because the .Name property of every column is an empty string ("") and does not get serialized to the designer codebehind file. This never happens with any other Winforms control (Label, Button, etc.) They always get their .Name written to the designer codebehind.
In some sense, this is a flaw in Winforms itself, because OLVColumn inherits from System.Windows.Forms.ColumnHeader, and a traditional ListView has exactly the same problem. .Name is always an empty string for all columns.
I would like to patch our local build of ObjectListView.dll to force populate the .Name property, but I can't figure out how Winforms automagically knows the name of every control on the form. It somehow(?) knows the names of the OLVColumn objects since it can display them in the Edit Columns... dialog on the ObjectListView's context menu. I'm also a little fuzzy on where the best spot is to plug this in.
(Yes, per linked question at top I know that as a last resort, I can hardcode colXX.Name = "colXX"; for all columns in my source code, but future column additions are likely to get overlooked and a programmatic solution is much preferred.)
(See also: https://sourceforge.net/p/objectlistview/bugs/160/ : the ObjectListView author declared this a wont-fix so it is up to me (or us), I guess.)
As you point out, this is a bug which is not with the ObjectListView, but the underlying component. And a bug which is around since at least 2008! Therefore, I doubt it will ever be fixed by MS.
Actually, it is a problem with the Autogenerated code in the designer.
If you look at other components such as a button, then the autogenerated code adds a name such as this;
//
// button2
//
this.button2.Location = new System.Drawing.Point(458, 199);
this.button2.Name = "button2";
...
But for ColumnHeader (Listview) and OLVColumn (ObjectListView), then this is not done, so then you end up with this.
//
// olvColumn1
//
this.olvColumn1.AspectName = "Name";
this.olvColumn1.Text = "Name";
If you manually add the line
this.olvColumn1.Text = "olvColumn1";
Then the "problem" is solved.
Of course, you can't do this, because the designer will override the autogenerated code when you make any changes, and then you will lose these manually added lines. It is also not sustainable.
So I'm afraid you need to code around this with some kind of ugly solution. Some options are:
Use the Tag to store the name and compare against this.
Use the text instead of the name (not possible if you have multi
language support!)
Code the names column manually in the Constructor
Set the Text to be something like "ColName;ColText" and then in your
code separate these out.
I have done option 3 in the past, but only I was maintaining the code, so this was easy.
What you could do to ensure you don't have discrepancies is to add a check in your constructor to compare the actual number of columns with the number you expect (hard coded for), and throw an exception if they don't match. Also, not the best, but another way to highlight and reduce errors.
The workaround for this is to get the OLVColumns via reflection and set their column's Name property at runtime. Every OLVColumn is a form-level field, so just pick them out of the list returned by GetFields().
Dim allFieldInfos As FieldInfo() = GetType(FrmMain).GetFields(BindingFlags.NonPublic or BindingFlags.Instance)
For Each fi As FieldInfo In allFieldInfos
If fi.FieldType Is GetType(OLVColumn) Then
Dim instance As OLVColumn = fi.GetValue(Me)
For Each col As OLVColumn In fdlvMain.AllColumns
If ReferenceEquals(col, instance) Then
col.Name = fi.Name
End If
Next
End If
Next

setting hierarchical property for GXT's ComboBox.setDisplayField

i have a simple extension of a BaseModelData in a form of MyModel, and i can call new MyModel().getObj1().getObj2() to get to obj2's string value. i have a number of MyModel instances, so i would like to populate a ComboBox instance with an obj2 value from each MyModel instance. first, i called ComboBox.setDisplayField("obj1.obj2"), because using such hierarchical property approach works for TextField.setName() cases. then, i took a store which contains all MyModel instances, and set it to a ComboBox via setStore(). however, the combobox is empty. it looks as though setting the aforementioned property via ComboBox.setDisplayField() does not work the same way as it does for TextField.setName(). i tried using my own instance of ListModelPropertyEditor, but without success. so what are my alternatives?
thank you for your time!!!
I am not sure about accessing hierarchical data from ComboBox.setDisplayField() method, but can you can achieve it by adding a new method say getObj2() in MyModel class, which will essentially represent obj1.obj2.
public Obj2 getObj2() {
return getObj1().getObj2(); //with possible null checks
}
Now you can call ComboBox.setDisplayField("obj2") and get the work done.

FrameworkElement.Name problem

I am attempting to set the Name property of a Page in the constructor:
public partial class PageListView : Page
{
public PageListView(string title)
{
InitializeComponent();
Name = title;
}
}
However, I often get the following error message.
'x' is not a valid value for property 'Name'.
Where x seems to be almost anything, drilling down into the exception details doesn't seem to provide any useful information (e.g. the InnerException is null.)
Does anyone know what is happening here?
The Name property generally follows the rules of C#/VB.NET identifiers (i.e. fields). Based on the documentation:
The string values used for Name have some restrictions, as imposed by
the underlying x:Name Directive defined by the XAML specification.
Most notably, a Name must start with a letter or the underscore character
(_), and must contain only letters, digits, or underscores.
Based on the parameter you are passing (i.e. title), it seems like you may violate that. But you'd have to give some specific examples to be sure.
Of course, moments after posting this I realised what's going on.
Because FrameworkElement.Name is used for creating object references, you have to ensure that the string contains only valid chars for an object instance variable name.
Use Title or another plain text property instead, unless you really want to set the x:Name property for referencing.

Strongly typed databinding in WPF/Silverlight/XAML?

One of my biggest pet peeves with how databinding works with XAML is that there's no option to strongly type your databindings. In other words, in C#, if you want to access a property on an object that doesn't exist, you won't get any help from Intellisense, and if you insist on ignoring Intellisense, the compiler will gripe at you and won't let you proceed -- and I suspect that lots of folks here would agree that this is a Very Good Thing. But in XAML databinding, you're operating without a net. You can bind to anything, even if it doesn't exist. Indeed, given the bizarre syntax of XAML databinding, and given my own experience, it's a great deal more complicated to bind to something that does exist than to something that doesn't. I'm much more likely to get my databinding syntax wrong than to get it right; and the comparative time I spend troubleshooting XAML databindings easily dwarfs the time I spend with any other portion of Microsoft's stack (including the awkward and annoying WCF, if you can believe it). And most of that (not all of it) goes back to the fact that without strongly-typed databindings, I can't get any help from either Intellisense or the compiler.
So what I want to know is: why doesn't MS at least give us an option to have strongly-typed databindings: kind of like how in VB6, we could make any object a variant if we were really masochistic, but most of the time it made sense to use normal, typed variables. Is there any reason why MS couldn't do that?
Here's an example of what I mean. In C#, if the property "UsrID" doesn't exist, you'll get a warning from Intellisense and an error from the compiler if you try this:
string userID = myUser.UsrID;
However, in XAML, you can do this all you want:
<TextBlock Text="{Binding UsrID}" />
And neither Intellisense, the compiler, or (most astonishingly) the application itself at runtime will give you any hint that you've done something wrong. Now, this is a simplistic example, but any real-world application that deals with complex object graphs and complex UI's is going to have plenty of equivalent scenarios that aren't simple at all, nor simple to troubleshoot. And even after you've gotten it working correctly the first time, you're SOL if you refactor your code and change your C# property names. Everything will compile, and it'll run without an error, but nothing will work, leaving you to hunt and peck your way through the entire application, trying to figure out what's broken.
One possible suggestion (off the top of my head, and which I haven't thought through) would maybe be something like this:
For any portion of the logical tree, you could specify in XAML the DataType of the object that it's expecting, like so:
<Grid x:Name="personGrid" BindingDataType="{x:Type collections:ObservableCollection x:TypeArgument={data:Person}}">
This would perhaps generate a strongly-typed ObservableCollection<Person> TypedDataContext property in the .g.cs file. So in your code:
// This would work
personGrid.TypedDataContext = new ObservableCollection<Person>();
// This would trigger a design-time and compile-time error
personGrid.TypedDataContext = new ObservableCollection<Order>();
And if you then accessed that TypedDataContext through a control on the grid, it would know what sort of an object you were trying to access.
<!-- It knows that individual items resolve to a data:Person -->
<ListBox ItemsSource="{TypedBinding}">
<ListBox.ItemTemplate>
<DataTemplate>
<!--This would work -->
<TextBlock Text="{TypedBinding Path=Address.City}" />
<!-- This would trigger a design-time warning and compile-time error, since it has the path wrong -->
<TextBlock Text="{TypedBinding Path=Person.Address.City} />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I've made a blog posting here that explains more about my frustrations with WPF/XAML databinding, and what I think would be a significantly better approach. Is there any reason why this couldn't work? And does anyone know if MS is planning to fix this problem (along the lines of my proposal, or hopefully, a better one)?
There will be IntelliSense support for data-binding in Visual Studio 2010. That seems to be what your complaint really boils down to, since data-binding is strongly-typed. You just don't find out until run-time whether or not the binding succeeded, and more often than not it fails quietly rather than with a noisy exception. When a binding fails, WPF dumps explanatory text via debug traces, which you can see in the Visual Studio output window.
Besides the lack of IntelliSense support and a few weird syntax issues, data-binding is quite well done (at least in my opinion). For some more assistance debugging data-bindings, I would check out Bea's lovely article here.
This is my biggest gripe with XAML! Not having the compiler enforce valid databindings is a BIG issue. I don't really care about intellisense, but I DO care about the lack of refactoring support.
Changing property names or types is dangerous in a WPF application - using the built in refactoring support won't update data bindings in XAML. Doing a search and replace on the name is dangerous as it may change code that you didn't intend to change. Going through a list of find results is a pain in the arse and time consuming.
MVC has had strongly typed views for some time - the MVC contrib project provided them for MVC1 and MVC2 provides them natively. XAML must support this in future, particularly if it is used in "agile" projects where an application's design evolves over time. I haven't looked at .NET 4.0 / VS2010, but I hope the experience is far better than it is!
I feel that xaml is sth like old-days html. i cannot imagine that after 10+ years, i am doing programming in that way: typing open-close tags manually because i cannot have a matured GUi for me to define styles and binding and templates. I strongly support your view, Ken. I feel very weird why so many people are supporting MVVM without a single complain about the pain in debugging xaml. Command binding and data binding are very good concepts and I have been designing my winform apps in that way. However, the xaml binding solution together with some other xaml issue (or lack of a sophisticated feature) is really a big failure in VS. It made the development and debug very difficult, and made the code very unreadable.
Ken, C# would benefit from a concise syntactical element for referencing a PropertyInfo class. PropertyInfo structures are static objects defined at compile time and as such provide a unique key for every Property on an object. Properties could then be validated at compile time.
The only problem with this is the weirdness of treating an instance of a object as a data type given that strong typing is enforced on types, not the values of a type. Traditionally, compilers don't enforce data values, and instead rely on runtime code to check its data. Most cases its not even possible to validate data at compile time, but reflection is one of those edge cases where it is at least possible.
Alternatively, the compiler could create a new data type for every property. I could imagine a lot of types being created, but that would enable compile time enforcement of property binding.
One way to think about it is that the CLR introduced a level of reflection that was another level of magnitude compared to the systems that preceded it. It's now being used to do some rather impressive stuff like data binding. But its implementation is still at a metadata level, a kind of report from the compiler for every data type is generates. I supposed one way to grow C# would be to promote the metadata to compile time checking.
It seems to me that someone could develop a compilation tool that adds that reflection level validation. The new intellisense is sorta like that. It would be tricky to generically discover string parameters that are destined to be compared to PropertyInfos, but its not impossible. A new data type like "PropertyString" could be defined that clearly identifies parameters that will be compared to PropertyInfos in the future.
Anyway, I feel your pain. I've chased down a lot of misspelled property name references. Honestly, there are a lot of irritations in WPF related to reflection. A useful utility would be a WPF enforcement checker that makes sure all your static control constructors are in place, your attributes properly defined, bindings are accurate, correct keys, etc. There is a long list of validations that could be performed.
If I were still working for Microsoft, I'd probably try doing it.
It sounds like what you are asking for would not require any framework changes, and possibly is already fixed in VS 2010 (I don't have it installed).
The XAML designer needs IntelliSense for bindings within a DataTemplate when you specify a DataType, which is already possible like so:
<DataTemplate DataType="{x:Type data:Person}">
...
</DataTemplate>
I agree that having IntelliSense in this case would be a helpful change, but your other suggestions seem to miss the point of being able to change DataContexts at runtime and use DataTemplates for different types to render them uniquely.
This is truly a solution to what you are wanting!
But, it isn't is a built-in, native, framework solution. Yes, I think that's what we all really want here. Maybe we'll get that later.
In the interim, if you are dead set on restricting the type, this solves that!
Using this converter:
public class RequireTypeConverter : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return value;
// user needs to pass a valid type
if (parameter == null)
System.Diagnostics.Debugger.Break();
// parameter must parse to some type
Type _Type = null;
try
{
var _TypeName = parameter.ToString();
if (string.IsNullOrWhiteSpace(_TypeName))
System.Diagnostics.Debugger.Break();
_Type = Type.GetType(_TypeName);
if (_Type == null)
System.Diagnostics.Debugger.Break();
}
catch { System.Diagnostics.Debugger.Break(); }
// value needs to be specified type
if (value.GetType() != _Type)
System.Diagnostics.Debugger.Break();
// don't mess with it, just send it back
return value;
}
public object ConvertBack(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Then, restrict your DataType like this:
<phone:PhoneApplicationPage.Resources>
<!-- let's pretend this is your data source -->
<CollectionViewSource x:Key="MyViewSource" Source="{Binding}"/>
<!-- validate data type - start -->
<converters:RequireTypeConverter x:Key="MyConverter" />
<TextBlock x:Key="DataTypeTestTextBlock"
DataContext="{Binding Path=.,
Source={StaticResource MyViewSource},
Converter={StaticResource MyConverter},
ConverterParameter=System.Int16}" />
<!-- validate data type - end -->
</phone:PhoneApplicationPage.Resources>
See how I am requiring the CollectionViewSource to have System.Int16? Of course, you can't even set the Source of a CVS to an Integer, so this will always fail. But it proves the point for sure. It's just too bad that Silverlight does not support {x:Type} or I could have done something like ConverterParameter={x:Type sys:Int16} which would have been nice.
Plus, that XAML should be non-intrusive, so you should be able to implement this without any risk. If the data type is ever what you do not want it to be then the debugger will break and you can kick yourself for breaking your own rule. :)
Again, I know this is a little funky, but it does what you want - in fact I have been playing with it while coding it and maybe I even have a use for it. I like that it's design-time/debuggin only. But, listen, I am not trying it sell it to you.
I am just having fun, if this is too much syntax, just enjoy my effort ;)
PS: you could also create an attached property of type Type that you could use the same way. You could attach it to your CVS or anything else, like x:RequiredType="System.Int16" and in the behavior of the property you could just repeat the converter logic. Same effect, probably the same amount of code - but another viable option if you are serious.
Okay I could not resist, here's the Attached Property approach:
Here's the XAML:
<phone:PhoneApplicationPage.Resources>
<!-- let's pretend this is your data source -->
<CollectionViewSource
x:Key="MyViewSource" Source="{Binding}"
converters:RestrictType.Property="Source"
converters:RestrictType.Type="System.Int16" />
</phone:PhoneApplicationPage.Resources>
Here's the property code:
public class RestrictType
{
// type
public static String GetType(DependencyObject obj)
{
return (String)obj.GetValue(TypeProperty);
}
public static void SetType(DependencyObject obj, String value)
{
obj.SetValue(TypeProperty, value);
Watch(obj);
}
public static readonly DependencyProperty TypeProperty =
DependencyProperty.RegisterAttached("Type",
typeof(String), typeof(RestrictType), null);
// property
public static String GetProperty(DependencyObject obj)
{
return (String)obj.GetValue(PropertyProperty);
}
public static void SetProperty(DependencyObject obj, String value)
{
obj.SetValue(PropertyProperty, value);
Watch(obj);
}
public static readonly DependencyProperty PropertyProperty =
DependencyProperty.RegisterAttached("Property",
typeof(String), typeof(RestrictType), null);
private static bool m_Watching = false;
private static void Watch(DependencyObject element)
{
// element must be a FrameworkElement
if (element == null)
System.Diagnostics.Debugger.Break();
// let's not start watching until each is set
var _PropName = GetProperty(element);
var _PropTypeName = GetType(element);
if (_PropName == null || _PropTypeName == null)
return;
// we will not be setting this up twice
if (m_Watching)
return;
m_Watching = true;
// listen with a dp so it is a weak reference
var _Binding = new Binding(_PropName) { Source = element };
var _Prop = System.Windows.DependencyProperty.RegisterAttached(
"ListenToProp" + _PropName,
typeof(object), element.GetType(),
new PropertyMetadata((s, e) => { Test(s); }));
BindingOperations.SetBinding(element, _Prop, _Binding);
// run now in case it is already set
Test(element);
}
// test property value type
static void Test(object sender)
{
// ensure element type (again)
var _Element = sender as DependencyObject;
if (_Element == null)
System.Diagnostics.Debugger.Break();
// the type must be provided
var _TypeName = GetType(_Element);
if (_TypeName == null)
System.Diagnostics.Debugger.Break();
// convert type string to type
Type _Type = null;
try
{
_Type = Type.GetType(_TypeName);
if (_Type == null)
System.Diagnostics.Debugger.Break();
}
catch { System.Diagnostics.Debugger.Break(); }
// the property name must be provided
var _PropName = GetProperty(_Element);
if (string.IsNullOrWhiteSpace(_PropName))
System.Diagnostics.Debugger.Break();
// the element must have the specified property
var _PropInfo = _Element.GetType().GetProperty(_PropName);
if (_PropInfo == null)
System.Diagnostics.Debugger.Break();
// the property's value's Type must match
var _PropValue = _PropInfo.GetValue(_Element, null);
if (_PropValue != null)
if (_PropValue.GetType() != _Type)
System.Diagnostics.Debugger.Break();
}
}
Best of luck! Just having fun.
Also, if you have your output window open when you're debugging your project, VS will inform you of any databinding errors, i.e. that the property a Control is bound to doesn't exist.
Guys,
What Ken and grant are trying to say is ..
How About have a XAMl where i can do like p.UserId)> where P is the DataContext of Type Customer
You can now!
http://msdn.microsoft.com/en-us/library/dd490796(VS.100).aspx

How can I edit immutable objects in WPF without duplicating code?

We have lots of immutable value objects in our domain model, one example of this is a position, defined by a latitude, longitude & height.
/// <remarks>When I grow up I want to be an F# record.</remarks>
public class Position
{
public double Latitude
{
get;
private set;
}
// snip
public Position(double latitude, double longitude, double height)
{
Latitude = latitude;
// snip
}
}
The obvious way to allow editing of a position is to build a ViewModel which has getters and setters, as well as a ToPosition() method to extract the validated immutable position instance. While this solution would be ok, it would result in a lot of duplicated code, especially XAML.
The value objects in question consist of between three and five properties which are usually some variant of X, Y, Z & some auxiliary stuff. Given this, I had considered creating three ViewModels to handle the various possibilities, where each ViewModel would need to expose properties for the value of each property as well as a description to display for each label (eg. "Latitude").
Going further, it seems like I could simplify it to one general ViewModel that can deal with N properties and hook everything up using reflection. Something like a property grid, but for immutable objects. One issue with a property grid is that I want to be able to change the look so I can have labels and textboxes such as:
Latitude: [ 32 ] <- TextBox
Longitude: [ 115 ]
Height: [ 12 ]
Or put it in a DataGrid such as:
Latitude | Longitude | Height
32 115 12
So my question is:
Can you think of an elegant way to solve this problem? Are there any libraries that do this or articles about something similar?
I'm mainly looking for:
Code duplication to be minimized
Easy to add new value object types
Possible to extend with some kind of validation
Custom Type Descriptors could be used to solve this problem. Before you bind to a Position, your type descriptor could kick in, and provide get and set methods to temporarily build the values. When the changes are committed, it could build the immutable object.
It might look something like this:
DataContext = new Mutable(position,
dictionary => new Position(dictionary["lattitude"], ...)
);
Your bindings can still look like this:
<TextBox Text="{Binding Path=Lattitude}" />
Because the Mutable object will 'pretend' to have properties like Lattitude thanks to its TypeDescriptor.
Alternatively you might use a converter in your bindings and come up with some kind of convention.
Your Mutable class would take the current immutable object, and a Func<IDictionary, object> that allows you to create the new immutable object once editing completes. Your Mutable class would make use of the type descriptor, which would create PropertyDescriptors that create the new immutable object upon being set.
For an example of how to use type descriptors, see here:
http://www.paulstovell.com/editable-object-adapter
Edit: if you want to limit how often your immutable objects are created, you might also look at BindingGroups and IEditableObject, which your Mutable can also implement.
I found this old question while researching my possible options in the same situation. I figured I should update it in case anyone else stumbles on to it:
Another option (not available when Paul offered his solution since .Net 4 wasn't out yet) is to use the same strategy, but instead of implementing it using CustomTypeDescriptors, use a combination of generics, dynamic objects and reflection to achieve the same effect.
In this case, you define a class
class Mutable<ImmutableType> : DynamicObject
{
//...
}
It's constructor takes an instance of the immutable type and a delegate that constructs a new instance of it out of a dictionary, just like in Paul's answer. The difference here, however, is that you override the TryGetMember and TrySetMember to populate an internal dictionary that you're eventually going to use as the argument for the constructor-delegate. You use reflection in order to verify that the only properties that you're accepting are those that are actually implemented in ImmutableType.
Performance wise, I wager that Paul's answer is faster, and doesn't involve dynamic objects, which are known to put C# developers into fits. But the implementation for this solution is also a little simpler, because Type Descriptors are a bit arcane.
Here's the requested proof-of-concept / example implementation:
https://bitbucket.org/jwrush/mutable-generic-example
Can you think of an elegant way to solve this problem?
Honestly, you just dance around the problem, but don't mention the problem itself ;).
If I correctly guess your problem, then the combination of MultiBinding and IMultiValueConverter should do the trick.
HTH.
P.S. BTW, you have immutable class instances, not value objects. With value objects (which are described by struct keyword) you would dance much more no matter if there were setters or not :).

Resources