Silverlight глубокая копия UIElement с помощью SetInalue PropertyInfo? - PullRequest
0 голосов
/ 27 декабря 2011

У меня есть RadComboBox от telerik, в котором есть несколько защищенных сеттеров для некоторых его свойств.Я хочу иметь возможность устанавливать каждое свойство, чтобы я получил его от этого элемента управления и создал собственный элемент управления.Я также сделал то же самое для его элемента items.

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, чтобы я мог получить доступ к установщику для каждого элементаиз первого списка на основе данных:

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 здесь:

Обновление свойств элемента ObservableCollection с использованием 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);
                }
            }
        }
    }
}

Резюме: Я пытаюсь создать собственный ComboBox из RadComboBox Telerik.Это имеет ComboBoxItems с защищенным установщиком свойств зависимостей IsHighlighted.Я создал MyCustomComboBoxItem, чтобы обойти это ограничение, но не могу скопировать RadComboBoxItem в MyCustomComboBoxItem.

Причина: Я хочу установить его, чтобы помочь пользователю влучший опыт.

Спасибо.

1 Ответ

0 голосов
/ 26 июля 2012

Свойство IsHightlighted в RadComboBoxItem является внутренним свойством и, вероятно, по уважительной причине.Если вы попытаетесь манипулировать свойством для своих собственных целей, результаты, вероятно, будут непредсказуемыми.

В своей основе свойство IsHighlighted просто используется для запуска изменений визуального состояния.Если вы просто хотите выделить элемент в определенных обстоятельствах, лучше всего будет

  • Создать копию RadComboBoxItem ControlTemplate (для этого проще всего использовать Blend).
  • Создайте производный класс (как вы уже сделали).
  • Добавьте свой собственный DependencyProperty (или свойство или метод в зависимости от того, как вы хотите его использовать) и измените TargetType на скопированных ControlTemplate и Style, чтобы они соответствовали DefaultStyleKey в вашем новом классе.

Теперь вам просто нужно добавить новую 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);
...