Как создать пользовательский контроль silverlight 4 со свойством зависимости, которое может принимать любой тип - PullRequest
1 голос
/ 22 апреля 2011

Я ищу способ создания UserControl в silverlight 4 и предоставления свойства зависимости, которое может принимать любой тип. Под этим я подразумеваю, например, если вы посмотрите на стандартный элемент управления Silverlight, такой как AutoCompleteBox, он способен обрабатывать любые типы коллекций. Таким образом, вы можете связать AutoCompleteBox с IEnumerable<Human> or IENumerable<Animal> и т. Д. И когда выбран какой-либо элемент, AutoCompleteBox возвращает выбранное значение либо экземпляр Human, либо экземпляр Animal через свойство зависимостей SelectedItem.

Я хочу добиться такой же гибкости с помощью моего usercontrol. Я хотел бы выставить 2 свойства зависимостей. Предлагаемые элементы и Выбранные элементы. Какая коллекция всегда установлена ​​в виде ApproItems через потребителей этого пользовательского элемента управления через Binding, давайте возьмем в качестве примера IEnumerable<Car> свойство I Want SelectedItem для отправки экземпляра типа Car обратно потребителю через Binding. Если я использовал IEnumerable<Boat>, то мне нужно, чтобы Boat был возвращен с SelectedItem.

Я пытался добиться этого, используя приведенный ниже пример с использованием MVVM, но он не работает. Я ищу некоторые подсказки относительно того, как это должно быть разработано, я даже на правильном пути, или я должен полностью изменить свой дизайн?

Я создал UserControl с именем VehicleSelectorUserControl, у которого есть собственный выделенный ViewModel с именем VehicleSelectorViewModel с двумя значениями свойств Предлагаемые элементы, Выбранный элемент.

И usercontrol имеет соответствующие свойства Dependency в своем коде, чтобы предоставить их потребителям usercontrol. UserControl XAML имеет ListBox, который связан со свойством предполагаемых элементов в VehicleSelectorViewModel. Когда пользователь делает выбор, устанавливается VehicleSelectorViewModel SelectedItem, который вызывает делегата с именем ItemSelected, чтобы уведомить VehicleSelectorUserControl codebehind, который затем устанавливает свойство SelectedItem Dependency, чтобы сделать его доступным для потребителя.

Ниже приведен код из кода VehicleSelectorUserControl.xaml.cs.

private VehicleSelectorViewModel _TheViewModel;
    public UserNameControl()
    {
        InitializeComponent();
        _TheViewModel = Resources["TheViewModel"] as VehicleSelectorViewModel;
        _TheViewModel.ItemSelected = OnItemSelected;
    }

    public IEnumerable<object> SuggestedItems
    {
        get { return (IEnumerable<object>)GetValue(SuggestedItemsProperty); }
        set { SetValue(SuggestedItemsProperty, value); }
    }
    public static readonly DependencyProperty SuggestedItemsProperty =
        DependencyProperty.Register("SuggestedItems", typeof(IEnumerable<object>), typeof(VehicleSelectorControl), new PropertyMetadata(OnSuggestedItemsSet));

    private static void OnSuggestedItemsSet(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        _TheViewModel.SuggestedItems = e.NewValue;
    }

    public object SelectedItem
    {
        get { return (String) GetValue(SelectedItemProperty); }
        set { SetValue(SelectedItemProperty, value); }
    }
    public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.Register("SelectedItem", typeof(object), typeof(VehicleSelectorControl), null);

    private void OnItemSelected()
    {
        SelectedItem = _TheViewModel.SelectedItem;
    }

его код ViewModel VehicleSelectorViewModel

public Action ItemSelected { get; set; }

    private dynamic _SelectedItem;

    public dynamic SelectedItem
    {
        get { return _SelectedItem; }
        set
        {
            if (value != _SelectedItem)
            {
                _SelectedItem = value;
                NotifyPropertyChanged("SelectedItem");
                if(ItemSelected != null) ItemSelected.Invoke();
            }
        }
    }


    private dynamic _SuggestedItems;

    public dynamic SuggestedItems
    {
        get { return _SuggestedItems; }
        set
        {
            if (value != _SuggestedItems)
            {
                _SuggestedItems = value;
                NotifyPropertyChanged("SuggestedItems");
            }
        }
    } 

XAML клиента будет выглядеть следующим образом (у Consumer есть собственная модель ViewModel, которая отвечает за поставку Recommended Cars [IEnumerable<Car>], BuiltBoats [IEnumerable<Boat>].

            <my:VehicleSelectorControl x:Name="MyCarSelectorControl" 
                                   SuggestedItems="{Binding SuggestedCars, Mode=TwoWay}"  
                                   SelectedItem="{Binding UserSelectedCar, Mode=TwoWay}" />

        <my:VehicleSelectorControl x:Name="MyBoatSelectorControl" 
                                   SuggestedItems="{Binding SuggestedBoats, Mode=TwoWay}"  
                                   SelectedItem="{Binding UserSelectedBoat, Mode=TwoWay}" />
...