我有一个来自telerik的RadComboBox,它有一些受保护的设置器,用于它的一些属性。我希望能够设置每个属性,所以我从该控件派生,我创建了一个自定义控件。我也为它的项目组件做了同样的事情。
public class RadComboBoxItem : ListBoxItem
{
...
public bool IsHighlighted
{
get
{
return (bool)GetValue(IsHighlightedProperty);
}
protected set
{
this.SetValue(IsHighlightedPropertyKey, value);
}
}
...
}
public class MyCustomComboBoxItem : RadComboBoxItem
{
public void HighlightItem(bool _default)
{
this.IsHighlighted = _default;
}
}
在我的情况下,我有一个RadComboBoxItems列表,我想创建一个MyCustomComboBoxItem类型的新列表,所以我可以根据数据访问第一个列表中每个项目的setter:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
...
foreach (RadComboBoxItem _item in _listOfRadComboBoxItems)
{
MyCustomComboBoxItem _customCBI = new MyCustomComboBoxItem();
_customCBI.Load(_customCBI.GetType(), _item, true);
_listOfCustomCBI.Add(_newB2);
}
}
}
我发现另一篇文章解释了我要做的事情,但我的情况有点不同,我从这里借用了Load方法:
Updating ObservableCollection Item properties using INotifyPropertyChanged
public static class ExtentionMethods
{
public static void Load<T>(this T target, Type type, T source, bool deep)
{
foreach (PropertyInfo property in type.GetProperties())
{
if (property.CanWrite && property.CanRead)
{
if (!deep || property.PropertyType.IsPrimitive || property.PropertyType == typeof(String))
{
property.SetValue(target, property.GetValue(source, null), null);
}
else
{
object targetPropertyReference = property.GetValue(target, null);
targetPropertyReference.Load(targetPropertyReference.GetType(), property.GetValue(source, null), deep);
}
}
}
}
}
回顾:我在这里要做的是从Telerik的RadComboBox创建一个自定义ComboBox。这有ComboBoxItems,它具有受保护的IsHighlighted依赖项属性setter。我创建了MyCustomComboBoxItem来规避这个限制,但我无法将RadComboBoxItem复制到MyCustomComboBoxItem。
原因:我希望能够设置它,因此我可以帮助用户获得更好的体验。
感谢。
答案 0 :(得分:0)
RadComboBoxItem中的IsHightlighted属性是一个内部属性,可能有充分的理由。如果您尝试为自己的目的操纵该属性,结果可能是不可预测的。
在它的核心,IsHighlighted属性仅用于触发视觉状态变化。 如果您只是想在特定情况下突出显示该项目,最好的方法是
现在您只需要将新的VisualStateGroup添加到控件模板中的现有集合中。该组中的VisualStates应至少包含一个空(默认)状态和自定义突出显示状态。最佳实践要求您突出显示的状态应仅影响不受其他状态影响的属性。
例如:
<ControlTemplate TargetType="controls:MyCustomComboBox">
<Grid x:Name="VisualRoot">
...
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates" ei:ExtendedVisualStateManager.UseFluidLayout="True">
...
<VisualStateGroup x:Name="MyHighlightStates">
<VisualState x:Name="NotHighlightedState" />
<VisualState x:Name="MyHightlightedState">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyHighlightElement" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="MyHighlightElement" Background="Yellow" Visibility="Collapsed"/>
...
</Grid>
</ControlTemplate >
最后,您只需要使用VisualStateManager来触发控件中方法的可视状态更改:
VisualStateManager.GoToState(this, "MyHightlightedState", true);