Issue when using custom class with indexes in data binding
I have in my application (Unity) a class for testing indexing in DataBindings in XAML:
That is used as a DataContext for a XAML with the contents:
When I run this as a WPF-application in Blend, all three TextBlock behave as expected:
Using Noesis+Unity, however, the final TextBlock (the one using my custom indexer) ends up empty. How come? Am I missing something?
Code: Select all
public class IndexTest
{
public IndexTest()
{
_list.Add("foobar");
_dict.Add("foo", "bar");
}
private List<string> _list = new List<string>();
private Dictionary<string, string> _dict = new Dictionary<string, string>();
private Lexicon _lex = new Lexicon();
public List<string> List { get { return _list; } }
public Dictionary<string, string> Dict { get { return _dict; } }
public Lexicon Lex { get { return _lex; } }
//Custom class with indexer.
public class Lexicon
{
public string this[string arg]
{
get
{
var str = "foo " + arg;
return str;
}
}
}
}
Code: Select all
<StackPanel>
<TextBlock Text="{Binding List[0]}"/>
<TextBlock Text="{Binding Dict[foo]}"/>
<TextBlock Text="{Binding Lex[foo]}"/>
</StackPanel>
Using Noesis+Unity, however, the final TextBlock (the one using my custom indexer) ends up empty. How come? Am I missing something?
-
sfernandez
Site Admin
- Posts: 3188
- Joined:
Re: Issue when using custom class with indexes in data bindi
Currently we only support indexers on classes that implement the IList or IDictionary interface.
You will have to implement the IDictionary interface on your Lexicon class meanwhile.
You can create a ticket in our bugtracker if you need this feature to be implemented.
You will have to implement the IDictionary interface on your Lexicon class meanwhile.
You can create a ticket in our bugtracker if you need this feature to be implemented.
Re: Issue when using custom class with indexes in data bindi
Implementing IDictionary would not be a problem, but I have a hard time getting that to work as well. Are there any specific parts of the interface that need to be implemented for it to work?
I have only implemented the indexer (the rest of the members just throw exceptions when accessed).
I have only implemented the indexer (the rest of the members just throw exceptions when accessed).
-
sfernandez
Site Admin
- Posts: 3188
- Joined:
Re: Issue when using custom class with indexes in data bindi
You also have to implement IDictionary.Contains() because we use it when trying to solve the binding.
Anyway, we have to improve our code to support simple indexer properties. Please add this feature to the bugtracker to follow the status of the implementation.
Anyway, we have to improve our code to support simple indexer properties. Please add this feature to the bugtracker to follow the status of the implementation.
Re: Issue when using custom class with indexes in data bindi
I have now implemented IDictionary, with implementations for IDictionary.Contains(), IDictionary.this[], IDictionary.ContainsKey(). I still can't access the indexes through data bindings. In fact, it seems none of the methods or properties from IDictionary are ever accessed. Any idea?
The Lexicon class looks as follows:
in the (simplified) XAML:
I have filed a ticket requesting proper support for custom indexers in data bindings.
The Lexicon class looks as follows:
Code: Select all
//NotifyPropertyChangedBase is simply an implementation of INotifyPropertyChanged
public class Lexicon : NotifyPropertyChangedBase, IDictionary<string, string>
{
//This is the backend class I am writing a wapper for.
private LanguageManager _mgr { get { return LanguageManager.Instance; } }
public SmartCultureInfo Culture
{
set
{
Debug.Log("New culture: " + value.nativeName);
_mgr.ChangeLanguage(value);
NotifyPropertyChanged("Item[]");
}
get
{
var mgr = _mgr;
return mgr.GetCultureInfo(mgr.LoadedLanguage);
}
}
public List<SmartCultureInfo> Languages
{
get { return _mgr.GetSupportedLanguages(); }
}
#region IDictionary
public bool ContainsKey(string key)
{
var found = _mgr.HasKey(key);
Debug.Log("Looking for key: " + key + " found: " + found );
return found;
}
public string this[string key]
{
get
{
Debug.Log("Fetch key: " + key);
return _mgr.GetTextValue(key);
}
set
{
Debug.Log("Calling set on indexer for key: " + key);
throw new System.NotSupportedException();
}
}
public bool Contains(KeyValuePair<string, string> item)
{
Debug.Log("Contains?");
var val = _mgr.GetTextValue(item.Key);
var contains = item.Value.Equals(val);
return contains;
}
#endregion
#region Not supported features
public bool TryGetValue(string key, out string value)
{
Debug.Log("Called TryGetValue");
throw new System.NotSupportedException();
}
public ICollection<string> Values
{
get { Debug.Log("Called Values"); throw new System.NotSupportedException(); }
}
public void Add(string key, string value)
{
Debug.Log("Called Add");
throw new System.NotSupportedException();
}
public bool Remove(string key)
{
Debug.Log("Called Remove");
throw new System.NotSupportedException();
}
public ICollection<string> Keys
{
get { Debug.Log("Called Keys"); throw new System.NotSupportedException(); }
}
public System.Collections.IEnumerator GetEnumerator()
{
Debug.Log("Called GetEnumerator");
throw new System.NotSupportedException();
}
public void Add(KeyValuePair<string, string> item)
{
Debug.Log("Called Add");
throw new System.NotSupportedException();
}
public void Clear()
{
Debug.Log("Called Clear");
throw new System.NotSupportedException();
}
public void CopyTo(KeyValuePair<string, string>[] array, int arrayIndex)
{
Debug.Log("Called CopyTo");
throw new System.NotSupportedException();
}
public int Count
{
get { Debug.Log("Called Count"); throw new System.NotSupportedException(); }
}
public bool IsReadOnly
{
get { Debug.Log("Called IsReadOnly"); throw new System.NotSupportedException(); }
}
public bool Remove(KeyValuePair<string, string> item)
{
Debug.Log("Called Remove");
throw new System.NotSupportedException();
}
IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
{
Debug.Log("Called GetEnumerator2");
throw new System.NotSupportedException();
}
#endregion
}
Code: Select all
<TextBlock Text="{Binding Lex[LeftBox]}"/>
<TextBlock Text="{Binding Lex[RightBox]}"/>
<ComboBox ItemsSource="{Binding Lex.Languages}" SelectedItem="{Binding Lex.Culture}"/>
I have filed a ticket requesting proper support for custom indexers in data bindings.
-
sfernandez
Site Admin
- Posts: 3188
- Joined:
Re: Issue when using custom class with indexes in data bindi
Ok, we will follow the status of this feature in the bugtracker.
Thanks for your collaboration.
Thanks for your collaboration.
Who is online
Users browsing this forum: Ahrefs [Bot] and 4 guests