Last active
August 29, 2015 14:03
-
-
Save cuppster/b4065d4d0377a739c622 to your computer and use it in GitHub Desktop.
Technique using a binding converter to return an object representing viewmodel state for displaying an adorner.
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.Globalization; | |
using System.Windows.Data; | |
namespace WpfApplication1 | |
{ | |
/* | |
see: http://cuppster.com/2014/07/10/using-the-state-pattern-for-adorning-in-xaml/ | |
<!-- in resources ... --> | |
<local:FooStateConverter x:Key="FooStateConverter" /> | |
<!-- data template for a specific state --> | |
<DataTemplate DataType="{x:Type local:FooStateDefaultAdorner}"> | |
<Canvas> | |
<Image Source="/Images/DefaultOverlay.png" Canvas.Left="5" Canvas.Top="5"/> | |
</Canvas> | |
</DataTemplate> | |
... | |
<!-- inside the data template for the view model for Foo --> | |
<Grid> | |
<Image Source="/Images/FooBaseImage.png"/> | |
<AdornerDecorator> | |
<ContentControl Content="{Binding Converter={StaticResource FooStateConverter}}"/> | |
</AdornerDecorator> | |
*/ | |
public class FooState | |
{ | |
// a base class is convient so that the generic state class | |
// can be more type-safe and return a known base class instead of 'object' | |
} | |
public class FooState<T> : FooState | |
{ | |
// each generic class declared will recieve its own _instance static member | |
// ... that's the trick | |
private static FooState _instance; | |
public FooState() | |
{ | |
_instance = this; | |
} | |
public new static Type GetType() | |
{ | |
// returns the type of the generic parameter NOT of this class | |
return typeof(T); | |
} | |
public static FooState Instance | |
{ | |
get | |
{ | |
if (null == _instance) | |
{ | |
Type t = GetType(); | |
Activator.CreateInstance(t); | |
} | |
return _instance; | |
} | |
} | |
} | |
public class FooStateDefaultAdorner : FooState<FooStateDefaultAdorner> | |
{ | |
// use a XAML DataTemplate to present this object | |
} | |
public class FooStateInvalidAdorner : FooState<FooStateInvalidAdorner> | |
{ | |
// use a XAML DataTemplate to present this object | |
} | |
public class FooStateConverter : IValueConverter | |
{ | |
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | |
{ | |
// Inspect viewmodel or model for state | |
// and create the appropriate FooState class | |
/* | |
1. cast 'value' to your view model class | |
2. query the state of the view model | |
3. return a specific FooState instance based on that state | |
e.g. | |
var myViewModel = object as MyViewModel; | |
if (myViewModel.IsDefault) | |
return FooStateDefaultAdorner.Instance; | |
else if (myViewModel.IsInvalid) | |
return FooStateInvalidAdorner.Instance; | |
*/ | |
// fall-through... | |
return null; | |
} | |
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | |
{ | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment