我正在尝试将MVVM设计模式应用于图表应用程序。在此应用程序中有不同的项目(例如矩形,圆形......)。我想将项目类型保存为模型中的枚举。
在我的模型视图中,我为每个项目类型(rectangleViewMode,circleViewMode,...)创建了一个类。
在我的视图中,我将数据模板应用于该类型,因此它呈现为圆形或矩形。
问题是......如何将模型中的枚举转换为需要的xxxViewMode?我有很多类型,我想要自动转换。
我是MVVM的新手,也许有更好的方法......所以欢迎更好的解决方案! :)
非常感谢
答案 0 :(得分:1)
我对其他回答者的看法略有不同,我不相信你只是想找到一种方法将枚举绑定到组合,我认为你正在寻找一种方法将枚举值与对象类型。如果我弄错了,请立即停止阅读:)
首先:我不确定将形状类型保存为枚举(或者甚至将形状与枚举相关联)是非常可扩展的。请继续阅读,我将在最后解释。
要将项类型与枚举关联,只需让该项通过属性返回相应的枚举值:
public CircleViewMode
{
public ShapeType Shape { get { return ShapeType.Circle; }}
}
public enum ShapeType
{
Circle,
Square,
Rectangle,
Triangle,
FancyShape1,
FancyShape2
}
这意味着您不必使用转换器或其他转换器机制。如果你想将一堆这些填充到组合中,那么它很简单 - 检查以下示例并在适当的位置插入断点以查看它是如何工作的。
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
new Example().Run();
Console.ReadKey();
}
}
public class Example : INotifyPropertyChanged
{
public void Run()
{
var availableShapes = AllMyShapes.Where(x => x.NumberOfSides == 4);
AvailableShapes = new List<KeyValuePair<string, Type>>
(from Shape s in availableShapes
select new KeyValuePair<string, Type>(
Enum.GetName(typeof(ShapeType), s.ShapeType)
,s.GetType()
));
//at this point any combobox you have bound to the AvailableShapes property will now carry a new list of shapes
}
public List<Shape> AllMyShapes
{
get
{
return new List<Shape>() { new Circle(){NumberOfSides=1, ShapeType=ShapeType.Circle}
,new Square(){NumberOfSides=4, ShapeType=ShapeType.Square}
,new Rectangle(){NumberOfSides=4, ShapeType=ShapeType.Rectangle}
,new Triangle(){NumberOfSides=3, ShapeType=ShapeType.Triangle}
,new FancyShape1(){NumberOfSides=10, ShapeType=ShapeType.FancyShape1}
,new FancyShape2(){NumberOfSides=30, ShapeType=ShapeType.FancyShape2}
};
}
}
public List<KeyValuePair<string, Type>> AvailableShapes
{
get { return _availableShapes; }
protected set
{
_availableShapes = value;
}
}
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private List<KeyValuePair<string, Type>> _availableShapes;
public event PropertyChangedEventHandler PropertyChanged;
}
public abstract class Shape
{
public int NumberOfSides { get; set; }
public ShapeType ShapeType { get; set; }
}
public class Square : Shape { }
public class Rectangle : Shape { }
public class Triangle : Shape { }
public class Circle : Shape { }
public class FancyShape1 : Shape { }
public class FancyShape2 : Shape { }
public enum ShapeType
{
Circle,
Square,
Rectangle,
Triangle,
FancyShape1,
FancyShape2
}
}
使用这种方法,您将拥有一个具有漂亮的人类可读形状名称的组合框,您可以立即获得所选项目的实际形状类型。将类Example
转换为抽象基础ViewModel将是一项微不足道的任务,您从中派生的任何ViewModel都将具有AvailableShapes
属性。
但回到我原来的可伸缩性 - 当你增加形状类型时,你还需要更新枚举。如果您运送新形状的库或允许用户创建自己的形状,这可能会有问题。最好将其保存为myShape.GetType().ToString()
,它返回一个字符串值,然后可以使用反射重新创建对象的实例。在上面显示组合中的项目的示例中,您可以获得List<Type>
可用形状并使用转换器从形状类型生成一个漂亮的人类可读名称(使用字符串资源文件,消除完全枚举。)
答案 1 :(得分:0)
根据您的需要,您可以使用转换器类:
(从How to bind RadioButtons to an enum?被盗)
public class EnumBooleanConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null)
return DependencyProperty.UnsetValue;
if (Enum.IsDefined(value.GetType(), value) == false)
return DependencyProperty.UnsetValue;
object parameterValue = Enum.Parse(value.GetType(), parameterString);
return parameterValue.Equals(value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string parameterString = parameter as string;
if (parameterString == null)
return DependencyProperty.UnsetValue;
return Enum.Parse(targetType, parameterString);
}
#endregion
}