- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Xceed Extended WPF Toolkit 在 PropertyGrid
中显示带有 [Flags]
属性的枚举。
[Flags]
public enum TestEnum
{
Test1 = 1,
Test2 = 2,
Test3 = 4,
Test4 = 8,
Test5 = 16,
Test6 = 32,
Test7 = 64,
}
因为我无法在编译时知道枚举定义,所以我会使用 EnumBuilder 动态创建一个枚举.
我创建了一个编辑器来将枚举显示为 CheckComboBox
:
public class CheckComboBoxEditor : TypeEditor<CheckComboBox>, ITypeEditor
{
protected override void SetValueDependencyProperty()
{
ValueProperty = CheckComboBox.SelectedValueProperty;
}
protected override CheckComboBox CreateEditor()
{
return new CheckComboBox();
}
protected override void ResolveValueBinding(PropertyItem propertyItem)
{
var _binding = new Binding("Value");
_binding.Source = propertyItem;
_binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
_binding.Mode = BindingMode.TwoWay;
_binding.Converter = CreateValueConverter();
BindingOperations.SetBinding(Editor, CheckComboBox.SelectedValueProperty, _binding);
var _binding2 = new Binding("Value");
_binding2.Source = propertyItem;
_binding2.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
_binding2.Mode = BindingMode.TwoWay;
_binding2.Converter = CreateValueConverter();
BindingOperations.SetBinding(Editor, CheckComboBox.SelectedItemProperty, _binding2);
Editor.ItemsSource = Enum.GetValues(propertyItem.Value.GetType());
}
}
如您所见,到目前为止,我已尝试分别绑定(bind) SelectedValue
和 SelectedItem
属性。 CreateValueConverter()
在基类中定义并返回 null
。
如果我在框中选择一些值并点击我的保存按钮,它会很好地工作 - 在我的模型中,我收到正确的枚举值。但它在另一个方向上不起作用 - 如果我为我的属性设置任何枚举值(有或没有标志),所有值都未选中并且内容区域是空。
你有解决这个问题的想法吗?
最佳答案
在这种情况下,对于带有 FlagsAttribute 的枚举,最通用的解决方案是为枚举的所有项目和选定项目使用 VM 中的特定字段。类似的东西:
XAML
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<xctkpg:PropertyGrid Grid.Row="1" SelectedObject="{Binding CurrentObject}" AutoGenerateProperties="False">
<xctkpg:PropertyGrid.EditorDefinitions>
<xctkpg:EditorTemplateDefinition TargetProperties="{x:Type local:TestEnum}">
<xctkpg:EditorTemplateDefinition.EditingTemplate>
<DataTemplate>
<xctk:CheckComboBox ItemsSource="{Binding Instance.Items}" SelectedValue="{Binding Instance.SelValue}" />
</DataTemplate>
</xctkpg:EditorTemplateDefinition.EditingTemplate>
</xctkpg:EditorTemplateDefinition>
</xctkpg:PropertyGrid.EditorDefinitions>
<xctkpg:PropertyGrid.PropertyDefinitions>
<xctkpg:PropertyDefinition TargetProperties="Value" />
</xctkpg:PropertyGrid.PropertyDefinitions>
</xctkpg:PropertyGrid>
</Grid>
C#
class MainWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ItemViewModel _currentObject = new ItemViewModel() { Value = TestEnum.Test3 | TestEnum.Test7 };
public ItemViewModel CurrentObject
{
get { return _currentObject; }
set
{
_currentObject = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CurrentObject)));
}
}
}
public class ItemViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private TestEnum _value;
public TestEnum Value
{
get { return _value; }
set
{
_value = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelValue)));
}
}
public string SelValue
{
get
{
return String.Join(",", Enum.GetValues(typeof(TestEnum)).OfType<TestEnum>().Where(v => (_value & v) != 0).Select(v => v.ToString()));
}
set
{
_value = value.Split(new[] { ','}, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).
Aggregate((TestEnum)0, (acc, val) => acc | (TestEnum)Enum.Parse(typeof(TestEnum), val));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelValue)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
}
}
public ObservableCollection<string> Items
{
get
{
return new ObservableCollection<string>(Enum.GetNames(typeof(TestEnum)));
}
}
}
2016 年 1 月 31 日更新为了使代码适用于动态生成的枚举,我进行了以下更改:
XAML
<xctkpg:EditorTemplateDefinition TargetProperties="Value">
C#
public class ItemViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public static readonly Type EnumType = GenerateEnumType();
private object _value;
public object Value
{
get { return _value; }
set
{
_value = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelValue)));
}
}
public string SelValue
{
get
{
return String.Join(",",
Enum.GetValues(EnumType).OfType<object>().Where(v => ((int)_value & (int)v) != 0).Select(v => v.ToString()));
}
set
{
var strings = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim());
_value = Enum.ToObject(EnumType, strings.Aggregate(0, (acc, val) => acc | (int)Enum.Parse(EnumType, val)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelValue)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value)));
}
}
public ObservableCollection<string> Items
{
get
{
return new ObservableCollection<string>(Enum.GetNames(EnumType));
}
}
public static Type GenerateEnumType()
{
string asmNameString = "flags_enum";
// Create Base Assembly Objects
AppDomain appDomain = AppDomain.CurrentDomain;
AssemblyName asmName = new AssemblyName(asmNameString);
AssemblyBuilder asmBuilder = appDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
// Create Module and Enumeration Builder Objects
ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule(asmNameString + "_module");
EnumBuilder enumBuilder = modBuilder.DefineEnum(asmNameString, TypeAttributes.Public, typeof(int));
Type fa = typeof(FlagsAttribute);
CustomAttributeBuilder attributeBuilder =
new CustomAttributeBuilder(fa.GetConstructor(new Type[0]), new object[0]);
enumBuilder.SetCustomAttribute(attributeBuilder);
for (int i = 0; i < 7; i++)
{
enumBuilder.DefineLiteral($"Test{i + 1}", 1 << i);
}
return enumBuilder.CreateType();
}
}
现在 ItemViewModel 的值可以这样设置:
ItemViewModel vm = new ItemViewModel();
vm.Value = Enum.ToObject(ItemViewModel.EnumType, 33);
关于c# - WPF 工具包 : CheckComboBox and [Flags] enum,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34941352/
鉴于此 export const slice = createSlice({ name: 'reducer', initialState: { }, reducers:
当创建新图表并添加系列(例如 ColumnSeries)和数据时,列将呈现为淡入动画类型,并在屏幕上绘制图表后瞬间出现。 有什么办法可以阻止这个动画的发生吗?或者,是否有办法强制图表在渲染之前完成动画
我正在尝试从 Java 的 JDK 导入 tools.jar,但每当我尝试创建 newInstance 时,都会收到 InstantiationException来自图书馆的类(class)。 到目前
我正在寻找 JavaScript RIA 工具包。我的要求是:漂亮的外观、免费的许可证和健全的 API。有什么想法吗? 这就是我到目前为止所发现的: ExtJS 专业人士 完美的外观 很多小部件 支持
jsPlumb工具包是否可以根据要绘制和连接的对象的数量和类型动态定位内容。我的意思是目前example他们给出的方法是,使用 css 来定位每个节点,当我们动态生成可视化时,这不是一个好的选择,因为
我正在 Linux 中创建磁盘分析器。我想知道哪个 Python 工具包可以帮助我使用 GUI。我目前正在尝试 Tkinter 有更好的东西吗? 最佳答案 “更好”是主观的。我很乐意提出我的意见,即没
我们正在构建一个调查网络应用程序,它允许用户在离线时向调查添加新记录,并在浏览器重新连接到服务器时上传。 我们已经确定这将需要离线存储,因此 google gears 似乎是一个显而易见的选择(我们知
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在寻找可以在 Linux 系统上使用 C++ 语言的 SOAP 工具包。我查看了 AXIS2C,但发现它的文档很少。不幸的是,gSoap 需要许可证,所以还有其他的吗? 最佳答案 我用于 C++
我只是想掌握我可以从中构建的 OpenGL,所以我正在寻找的只是构建 Windows 等的基本知识。我在阅读教程时注意到的一件事就是它似乎就像很多信息已经过时了 - 例如很多教程(其中许多是几年前写的
有谁知道如何在 Silverlight 工具包的 TreeView 中实现拖放? 我看到了 Silverlight 的拖放管理器,但据说您可以在要拖放的项目周围放置容器,但我想知道如何在另一个 Tre
已结束。此问题不符合 Stack Overflow guidelines .它目前不接受答案。 我们不允许提出有关书籍、工具、软件库等方面的建议的问题。您可以编辑问题,以便用事实和引用来回答它。 关闭
我有一个有 6 列的 DataGrid,每列都是一个 RadioButton,以便用户可以选择 1 in 6 选项。大约有100行。我用 6 个 bool 数据成员创建了一个自定义类,然后将数据网格与
从我发现的一个 Silverlight 论坛页面,我的印象是在后面的代码中创建的 ChildWindow 会选择页面其余部分的主题;只有当您从 ChildWindow 继承时,情况才不再如此。 出于某
我正在使用 WPF 工具包 AutoCompleteBox,它的 itemsSource 是一个包含数百万个对象的列表。 AutoCompleteBox 是否用于搜索后台线程,如果没有,我该如何实现。
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 8年前关闭。 Improve this qu
这个问题已经有答案了: What is the difference between a framework and a library? [closed] (22 个回答) 已关闭 7 年前。 框架
我的问题很简单,我想通过一个简单的例子得到清晰的答案。 API、工具包、框架和库之间的主要区别是什么? 最佳答案 我更喜欢以下内容: API 是如何使用应用程序的抽象描述。例如,API可以描述聊天服务
我有一个 C# 应用程序。目前所有模块都是用 .NET 2 编写的,并且它使用一些具有 Linux 端口的可执行文件。所以我想知道我应该在 Windows 和 MacOS 上使用什么工具包才能在两者上
这是我非常简单的 Accordion XAML :- 如果我非常快地点击 Accordion 项目几次,我会得到这个异常:- AccessViolation
我是一名优秀的程序员,十分优秀!