Last active
August 29, 2015 14:01
-
-
Save ChadSki/e8af798636e9096e95fb to your computer and use it in GitHub Desktop.
Databinding to Dynamic Objects?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Windows; | |
using System.Windows.Controls; | |
using Quickbeam.Low; | |
namespace MetroIde.Controls.MetaEditor | |
{ | |
public class FieldControlSelector : DataTemplateSelector | |
{ | |
private static readonly Dictionary<Type, string> DataTemplateKeys = new Dictionary<Type, string> | |
{ | |
/* Signed ints */ | |
{typeof (SByte), "Int8FieldTemplate"}, | |
{typeof (Int16), "Int16FieldTemplate"}, | |
{typeof (Int32), "Int32FieldTemplate"}, | |
{typeof (Int64), "Int64FieldTemplate"}, | |
/* Unsigned ints */ | |
{typeof (Byte), "UInt8FieldTemplate"}, | |
{typeof (UInt16), "UInt16FieldTemplate"}, | |
{typeof (UInt32), "UInt32FieldTemplate"}, | |
{typeof (UInt64), "UInt64FieldTemplate"}, | |
/* Floating-point */ | |
{typeof (Single), "Float32FieldTemplate"}, | |
{typeof (Double), "Float64FieldTemplate"}, | |
/* String */ | |
{typeof (String), "StringFieldTemplate"}, | |
/* Reflexive */ | |
{typeof (IEnumerable<ObservableObject>), "ReflexiveFieldTemplate"}, | |
}; | |
public override DataTemplate SelectTemplate(object item, DependencyObject container) | |
{ | |
var o = item as ObservableAttribute<dynamic>; | |
if (o == null) | |
return null; | |
var key = DataTemplateKeys[o.Value.GetType()]; | |
return Application.Current.Resources[key] as DataTemplate; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:low="clr-namespace:Quickbeam.Low;assembly=Quickbeam.Low"> | |
<!-- Integers --> | |
<DataTemplate x:Key="Int8FieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:Int8Attribute.Value)}"/> | |
</DataTemplate> | |
<DataTemplate x:Key="Int16FieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:Int16Attribute.Value)}"/> | |
</DataTemplate> | |
<DataTemplate x:Key="Int32FieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:Int32Attribute.Value)}"/> | |
</DataTemplate> | |
<DataTemplate x:Key="Int64FieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:Int64Attribute.Value)}"/> | |
</DataTemplate> | |
<DataTemplate x:Key="UInt8FieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:UInt8Attribute.Value)}"/> | |
</DataTemplate> | |
<DataTemplate x:Key="UInt16FieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:UInt16Attribute.Value)}"/> | |
</DataTemplate> | |
<DataTemplate x:Key="UInt32FieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:UInt32Attribute.Value)}"/> | |
</DataTemplate> | |
<DataTemplate x:Key="UInt64FieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:UInt64Attribute.Value)}"/> | |
</DataTemplate> | |
<!-- Floating-point --> | |
<DataTemplate x:Key="Float32FieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:Float32Attribute.Value)}"/> | |
</DataTemplate> | |
<DataTemplate x:Key="Float64FieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:Float64Attribute.Value)}"/> | |
</DataTemplate> | |
<!-- String --> | |
<DataTemplate x:Key="StringFieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:StringAttribute.Value)}"/> | |
</DataTemplate> | |
<!-- Reflexive --> | |
<DataTemplate x:Key="ReflexiveFieldTemplate"> | |
<TextBlock Text="{Binding Path=(low:ReflexiveAttribute.Value)}"/> | |
</DataTemplate> | |
</ResourceDictionary> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.ObjectModel; | |
using System.ComponentModel; | |
using Quickbeam.Low.Annotations; | |
namespace Quickbeam.Low | |
{ | |
/// <summary> | |
/// An observable collection of observable attributes. This object fires | |
/// ICollectionChanged events when attributes are added or removed, and the | |
/// attributes themselves provide INotifyPropertyChanged events. | |
/// </summary> | |
public class ObservableObject : ObservableCollection<ObservableAttribute<dynamic>> | |
{ | |
} | |
/// <summary> | |
/// Wraps a T value and provides INotifyPropertyChanged events. Does not allow setting | |
/// the value through this interface. | |
/// </summary> | |
/// <typeparam name="T">The type of value contained in this field.</typeparam> | |
public abstract class ObservableAttribute<T> : INotifyPropertyChanged | |
{ | |
#region INotifyPropertyChanged | |
public event PropertyChangedEventHandler PropertyChanged; | |
[NotifyPropertyChangedInvocator] | |
protected virtual void OnPropertyChanged(string propertyName) | |
{ | |
if (PropertyChanged != null) | |
PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); | |
} | |
#endregion | |
protected T CachedValue; | |
public T Value | |
{ | |
get { return CachedValue; } | |
} | |
} | |
/// <summary> | |
/// Wraps a T value and provides INotifyPropertyChanged events. Does not allow setting | |
/// the value. | |
/// </summary> | |
/// <typeparam name="T"></typeparam> | |
public abstract class UpdatableAttribute<T> : ObservableAttribute<T> where T : IComparable | |
{ | |
public new T Value | |
{ | |
get { return CachedValue; } | |
set | |
{ | |
if (CachedValue.Equals(value)) return; | |
OnPropertyChanged("Value"); | |
CachedValue = value; | |
} | |
} | |
} | |
// Signed ints | |
public class Int8Attribute : UpdatableAttribute<SByte> { } | |
public class Int16Attribute : UpdatableAttribute<Int16> { } | |
public class Int32Attribute : UpdatableAttribute<Int32> { } | |
public class Int64Attribute : UpdatableAttribute<Int64> { } | |
// Unsigned ints | |
public class UInt8Attribute : UpdatableAttribute<Byte> { } | |
public class UInt16Attribute : UpdatableAttribute<UInt16> { } | |
public class UInt32Attribute : UpdatableAttribute<UInt32> { } | |
public class UInt64Attribute : UpdatableAttribute<UInt64> { } | |
// Floating-point | |
public class Float32Attribute : UpdatableAttribute<Single> { } | |
public class Float64Attribute : UpdatableAttribute<Double> { } | |
// String | |
public class StringAttribute : UpdatableAttribute<String> { } | |
// Reflexive groups aren't updatable yet, but the properties within a reflexive are | |
public class ReflexiveAttribute : ObservableAttribute<ObservableObject> { } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Prototype for databinding to dynamic objects.
Objects are collections of attributes and notify when attributes have been added or removed.
Attributes contain a single value and notify when that value has changed.
Attributes can hold a primitive type or an IEnumerable list of sub-objects.
Unfortunately, WPF does not play nice with generic types, so concrete subclasses had to be made.