2011-12-27 66 views
0

我有一个来自telerik的RadComboBox,它的一些属性有一些受保护的setter。我希望能够设置每个属性,以便从该控件派生出来,并创建了一个自定义控件。我也为它的项目组件做了同样的事情。使用PropertyInfo的SetValue Silverlight的UIElement深层副本?

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创建一个自定义组合框。这有ComboBoxItems具有IsHighlighted依赖属性设置程序保护。我创建了MyCustomComboBoxItem来绕过这个限制,但我无法将RadComboBoxItem复制到MyCustomComboBoxItem中。

原因:我希望能够设置它,所以我可以帮助用户获得更好的体验。

谢谢。

+0

不宜属性是依赖属性? – 2011-12-28 07:35:58

+0

在我的项目中,受保护的属性是依赖属性。我只是试图简化这个例子。我想要做的是创建一个基于Telerik的RadComboBox的自定义组合框,其中IsHighlighted属性是具有受保护的setter的属性。我需要提供突出显示机制,因为我不想为用户选择一个项目,但我想让他更接近最终选择。 – asuciu 2011-12-28 14:57:10

回答

0

RadComboBoxItem中的IsHightlighted属性是一个内部属性,可能有很好的理由。如果您试图为了您自己的目的操纵该财产,结果可能是不可预测的。

在它的心脏,IsHighlighted属性仅用于触发视觉状态更改。 如果你只是想强调按给定的情况下该项目时,最好的办法是

  • 创建RadComboBoxItem的ControlTemplate的副本(使用Blend是最简单的为这个)。
  • 创建一个派生类(就像你已经)。
  • 添加您自己的DependencyProperty(或属性或方法,具体取决于您想如何使用它),并更改复制的ControlTemplate和Style上的TargetType以匹配新类中的DefaultStyleKey。

现在只需将新的VisualStateGroup添加到控件模板中的现有集合中即可。该组中的VisualState应至少包含一个空白(默认)状态和自定义突出显示的状态。最佳做法表明,突出显示的状态只应影响不受其他州影响的属性。

例如:

<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);