2011-12-27 67 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);