Bind to specific item in collection without indexer - wpf

I am using an EF5 datamodel, in which the related entities are collected into a HashSet. I want to bind an element to the first related entity in the HashSet. I've seen answers on SO (here and here) which suggest using the following:
<DataGridComboBoxColumn SelectedValueBinding="{Binding LeadSteps[0].NewZoneID}"/>
but this relies on the collection having an indexer, which HashSet doesn't have.
(If this cannot be done, I can create a property in a partial class to the entity, and bind to that.)
How can I bind to the n-th item in a collection when the collection doesn't implement an integral indexer?

I know it's an old question, but i also ran into just the same problem and found a solution i thought to share.
What worked for me was changing the declaration of the referencing member from:
public virtual ICollection<MyType> MyVarName { get; set; }
to:
public virtual IList<MyType> MyVarName { get; set; }
After this change, the collection items were accessible with the normal accessor:
<TextBlock Text="{Binding MyVarName[0].MyMemberName}" />

You might need to rethink this whole situation. A HashSet is a 'set' of unique items, not a collection. A set is simply meant to maintain a group of members and to enable you to check whether a particular item is a member or not... there's no indexing because there is no order amongst the set items.
Although you can call the Enumerable.ElementAt<TSource> method on a HashSet, you cannot guarantee that it will return the same element when providing the same input value to the method. Most importantly, if the order of items in the HashSet is important to you, then you should be using a collection instead.
However, if you choose to ignore this advise, this is how you could achieve your requirement... just define a wrapper property for your single HashSet value... you could try something like this:
public YourHashSetDataType Hash
{
get { return LeadSteps.ElementAt(0).NewZoneID; }
set { LeadSteps.ElementAt(0).NewZoneID = value; NotifyPropertyChanged("Hash"); }
}

Related

using array of array of list of lists? C#

Im not an IT guy and trying some programming in his spare time and was wondering how to tackle following issue. It must be very very simple but can`t figure it out, even after dozen of read articles on stackoverflow.
I have a series of values which I need to put in a list or array which goes in another array or list. Like this:
Series one:
"name","Madman"
"dateOfBirth", 11/03/1990 //which is a DateTime object.
"hobby","chopping up family members"
Series two
"name","Dad"
"dateOfBirth", 11/03/1965 //which is a DateTime object.
"hobby","biking"
Series one and two go in another list like this:
allSeries: Series one, Series two
Any ideas? Thanks very much!
Create a class (possibly named Person) that has attributes name, dateOfBirth, and hobby (this encapsulates the data). Set the data through a constructor or setter methods. Then store the instances of Person into a list, or array, or whatever you choose - probably called people. Example: List<Person> people = new List<Person>();.
In your original approach you would have had to have declared your storage data structure as a more generic type. A nice bonus of this approach is that you know the types of the data stored in the class.
so depending on the language you are using you would make another list/array and make an array of arrays (or array of lists). Which language are you using? in Java you would make a List<List<String>> object for example and add things like this. Hope this is a start.
Edit: for c# see: http://www.dotnetperls.com/nested-list
I would do this: create a class containing your attributes, then place multiple instances in a list.
public class Person
{
public string name {get;set;}
public Date dateOfBirth {get; set;}
public string hobby {get;set;}
}
And place them in a list like so: {person1; person2,...}

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.

MarkupExtension that uses a DataBinding value

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.

How to assignTo a setter in Salesforce that requires an index parameter, such as a List<>?

In a controller I have two values:
public List<String> StringValue {get; set;}
public List<String> ListValue {get; set;}
The ListValue is initialized in the constructor and several strings are added. At this point in a value I can refer to these with {!StringValue} and {!ListValue[1]} in a VisualForce page. The list one in particular is the focus - I can even add pseudo-constants (getters) as indexes, making {!ListValue[nameIndex]} a valid reference.
However I've run into an exception when trying to set a list value instead of a simple string value.
<apex:param value="123" assignTo="{!ListValue[1]}" />
The exception is java.lang.ClassCastException: java.lang.String cannot be cast to common.formula.FormulaFieldReference
I think I understand the basics of the problem - Salesforce can't create a setter reference that includes an index parameter (meaning only setters that take a single parameter can be referenced).
Is there any way around this, or do I just have to create a massive amount of ListValue1, ListValue2 variables and associated code?
It's a hack, but it avoids you having to create dozens of variables.
<apex:param value="1:123" assignTo="{!smartAssigner}" />
Then in your controller:
public void setSmartAssigner(String myval) { // parse the colon, set list value appropriately.
You get the idea.
I've never come across a way to do this in the style you're requesting, I'd suggest that to get this going the easiest thing to do would be to concatenate the values you want into one parameter and then split them back up inside the controller.
You might find a suitable way to do this with <apex:repeat> but I'm not sure on your full use case.

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