-6ren">
gpt4 book ai didi

c# - xceed 属性网格 : choose between sets of custom propertydefinitions

转载 作者:行者123 更新时间:2023-11-30 23:22:25 25 4
gpt4 key购买 nike

到目前为止,我将 Xceed propertygrid 与 AutoGenerateProperties="True" 一起使用,并使用 [Browsable(false)] 指定我不想显示的属性> 属性。

现在我有一个案例,我只需要显示一部分属性,具体取决于其他属性的值。

我认为答案是使用PropertyDefinitions,如图here .

但该示例仅展示了如何实现将用于每个检查对象的一组 PropertyDefinitions

关于如何定义多组 PropertyDefinitions 并选择何时使用它们,您是否有提示或示例?

最佳答案

抱歉,这是一个冗长的回答。我也曾经使用过 AutoGenerateProperties="True" 但是我遇到了类似的问题。

我最终的解决方案是按照您的建议填充 PropertyDefinition。我以编程方式执行此操作,因为我最终遇到了一些相当特殊的情况,这些情况需要根据某处集合的内容动态创建属性。我注意到的一件事是,即使通过编程检查我的类来模拟 AutoGenerateProperties="True" 功能,我的速度也比他们的解决方案快得多。

为了按照您的要求处理可见性,尽管我必须创建自己的 Attribute 以使项目从 PropertyGrid 中不可见。

public class VisibilityAttribute : Attribute
{
public Visibility Visibility { get; private set; }

public VisibilityAttribute(Visibility visibility)
{
this.Visibility = visibility;
}
}

在我的项目中可以选择的每个项目都有自己的 PropertySetBase 类实现,该类具有如下属性定义:

[Category("Appearance"), LocalisedProperty(typeof(PropertySetBase), "LocalBackground", "LocalBackgroundDescription"), Editor(typeof(OptionalBrushEditor), typeof(OptionalBrushEditor)),
PropertyOrder(0)]
public virtual OptionalProperty<Brush> LocalBackground { get; set; }

然后处理 currentPropertySelection 集合中的 PropertySetBase 的逻辑。

private void PreparePropertyGrid()
{
PropertyDefinitionCollection propertyDefinitions = new PropertyDefinitionCollection();

// This is how I determine
var mainPropertySet = this.currentPropertySelection.FirstOrDefault();

if (mainPropertySet != null)
{
var properties = TypeDescriptor.GetProperties(mainPropertySet.GetType());
// Allowing for multiple selection, if on further iterations through the selected items we will remove properties that do not exist in both PropertySets
bool firstIteration = true;

foreach (var x in this.currentPropertySelection)
{
foreach (var p in properties.Cast<PropertyDescriptor>())
{
if (!firstIteration)
{
// Perhaps we should be checking a little more safely for TargetProperties but if the collection is empty we have bigger problems.
var definition = propertyDefinitions.FirstOrDefault(d => string.Equals(d.TargetProperties[0] as string, p.Name, StringComparison.Ordinal));

// Someone in the selection does not have this property so we can ignore it.
if (definition == null)
{
continue;
}

// If this item doesn't have the property remove it from the display collection and proceed.
var localProperty = x.GetType().GetProperty(p.Name);
if (localProperty == null)
{
propertyDefinitions.Remove(definition);
continue;
}

// There is actually no point in proceeding if this is not the first iteration and we have checked whether the property exists.
continue;
}

string category = p.Category;
string description = p.Description;
string displayName = p.DisplayName ?? p.Name;
int? displayOrder = null;
bool? isBrowsable = p.IsBrowsable;
bool? isExpandable = null;

var orderAttribute = p.Attributes[typeof(PropertyOrderAttribute)] as PropertyOrderAttribute;
if (orderAttribute != null)
{
displayOrder = orderAttribute.Order;
}

var expandableAttribute = p.Attributes[typeof(ExpandableObjectAttribute)] as ExpandableObjectAttribute;
if (expandableAttribute != null)
{
isExpandable = true;
}

propertyDefinitions.Add(new PropertyDefinition
{
Category = category,
Description = description,
DisplayName = displayName,
DisplayOrder = displayOrder,
IsBrowsable = isBrowsable,
IsExpandable = isExpandable,
TargetProperties = new[] { p.Name },
});
}
}

firstIteration = false;

this.propertyGrid.PropertyDefinitions = propertyDefinitions;
}
}

在实际显示/隐藏属性时,我执行了以下操作:

public void UpdateProperties(Tuple<string, bool?, Visibility?>[] newPropertyStates)
{
// Note this currently works under the assumption that an Item has to be selected in order to have a value changed.
this.suppressPropertyUpdates = true;

foreach (var property in newPropertyStates)
{
string propertyName = property.Item1;

string[] splits = propertyName.Split('.');
if (splits.Length == 1)
{
this.propertyGrid.Properties.OfType<PropertyItem>()
.Where(p => string.Equals(p.PropertyDescriptor.Name, propertyName, StringComparison.Ordinal))
.Map(p =>
{
if (property.Item2.HasValue)
{
p.IsEnabled = property.Item2.Value;
}

if (property.Item3.HasValue)
{
p.Visibility = property.Item3.Value;
}
});

}
else // We currently don't expect to go any lower than 1 level.
{
var parent = this.propertyGrid.Properties.OfType<PropertyItem>()
.Where(p => string.Equals(p.PropertyDescriptor.Name, splits[0], StringComparison.Ordinal))
.FirstOrDefault();

if (parent != null)
{
parent.Properties.OfType<PropertyItem>()
.Where(p => string.Equals(p.PropertyDescriptor.Name, splits[1], StringComparison.Ordinal))
.Map(p =>
{
if (property.Item2.HasValue)
{
p.IsEnabled = property.Item2.Value;
}
if (property.Item3.HasValue)
{
p.Visibility = property.Item3.Value;
}
});
}
}
}

this.suppressPropertyUpdates = false;
}

然后在 PreparePropertyItem 事件处理程序中,我检查我的 VisibilityAttribute 并相应地更新属性项。

void PropertyGrid_PreparePropertyItem(object sender, PropertyItemEventArgs e)
{
foreach (var x in this.currentPropertySelection)
{
// If we are in read-only mode do not allow the editing of any property.
if (this.IsReadOnly)
{
e.PropertyItem.IsEnabled = false;
}

string propertyName = ((PropertyItem)e.PropertyItem).PropertyDescriptor.Name;
PropertyInfo property = x.GetType().GetProperty(propertyName);
var propertyItem = e.Item as PropertyItem;

// If the property doesn't exist then check to see if it is on an expandable item.
if (property == null)
{
property = propertyItem.Instance.GetType().GetProperty(propertyName);
}

bool hasProperty = property != null;

if (hasProperty)
{
var browsableAttribute = property.GetCustomAttribute<BrowsableAttribute>(true);
if (browsableAttribute != null &&
!browsableAttribute.Browsable)
{
e.PropertyItem.Visibility = Visibility.Collapsed;
e.Handled = true;
break;
}

var visibilityAttribute = property.GetCustomAttribute<VisibilityAttribute>(true);
if (visibilityAttribute != null)
{
e.PropertyItem.Visibility = visibilityAttribute.Visibility;
e.Handled = true;
}

var independentAttribute = property.GetCustomAttribute<IndependentAttribute>(true);
// If a property is marked as being independent then we do not allow editing if multiple items are selected
if (independentAttribute != null &&
this.currentPropertySelection.Length > 1)
{
e.PropertyItem.IsEnabled = false;
e.Handled = true;
break;
}
}
}
}

关于c# - xceed 属性网格 : choose between sets of custom propertydefinitions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38783975/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com