WPF: нужна помощь в привязке UserControl - PullRequest
0 голосов
/ 24 января 2011

Я пытаюсь создать UserControl, который включает 2 списка. Затем я не хочу устанавливать itemsSources для списков, в которых я использую UserControl.

Насколько я понимаю, для этого DependencyProperties. Однако я не преуспел в этом. Я верю, что это в основном связано со временем инициализации. Любой указатель на то, что я делаю правильно, как я могу сделать это лучше, и такое приветствуется.

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

    <Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="2*" />
        <ColumnDefinition />
        <ColumnDefinition Width="2*" />
    </Grid.ColumnDefinitions>

    <ListBox Name="SET" ItemsSource="{Binding Path=SetCollection}" />

    <UniformGrid Rows="4" Grid.Column="1">

        <Grid />

        <Button Margin="10" Click="selectionBtnClick">--></Button>

        <Button Margin="10" Click="removeBtnClick">Remove</Button>

    </UniformGrid>

    <ListBox Name="SUBSET" ItemsSource="{Binding Path=SubsetCollection}" Grid.Column="2" />

</Grid>

CodeBehind

public partial class SubsetSelectionLists : UserControl
{
    public static DependencyProperty SetCollectionProperty = DependencyProperty.Register("SetCollection", typeof(CollectionView), typeof(SubsetSelectionLists));
    public static DependencyProperty SubsetCollectionProperty = DependencyProperty.Register("SubsetCollection", typeof(CollectionView), typeof(SubsetSelectionLists));

    public CollectionView SetCollection
    {
        get
        {
            return (CollectionView) GetValue(SetCollectionProperty);
        }
        set
        {
            SetValue(SetCollectionProperty, value);
        }
    }

    public CollectionView SubsetCollection
    {
        get
        {
            return (CollectionView)GetValue(SubsetCollectionProperty);
        }
        set
        {
            SetValue(SubsetCollectionProperty, value);
        }
    }

    public SubsetSelectionLists()
    {
        InitializeComponent();
    }

    private void selectionBtnClick(object sender, RoutedEventArgs e)
    {
        SUBSET.Items.Add(SET.SelectedItem);
    }

    private void removeBtnClick(object sender, RoutedEventArgs e)
    {
        SUBSET.Items.Remove(SUBSET.SelectedItem);
    }
}

И код где я его использую

public partial class SomeWindow : Window
{
    ViewModel vm = new ViewModel();

    public SomeWindow()
    {
        InitializeComponent();
        NameOfUserControl.SetCollection = vm.InputView;
        NameOfUserControl.SubsetCollection = vm.OutputView;
    }
}

Здесь SetCollection устанавливается как inputView, а затем привязывается к свойству DependencyProperty, разрывая исходную привязку, я думаю. Любая идея, где я иду не так?

Ps. подвопрос - Поскольку я буду перемещаться из одной коллекции в другую, разве я не должен гарантировать, что коллекция удерживает объекты одного и того же типа? Как я мог это сделать?

1 Ответ

1 голос
/ 24 января 2011

Прежде всего вы должны установить для свойства DataContext в SomeWindow значение vm. Это позволит очень простое выражение привязки в вашем SomeWindow.xaml.

public partial class SomeWindow : Window
{
    ViewModel vm = new ViewModel();

    public SomeWindow()
    {
        InitializeComponent();
        this.DataContext = vm;
    }
}

В SomeWindow.xaml:

<local:SubsetSelectionLists
    SetCollection="{Binding Path=InputView}"
    SubsetCollection ="{Binding Path=OutputView}" />

Существует несколько способов решения проблемы привязки в пользовательском элементе управления:

Настройка контекста данных

Добавьте следующее в конструктор пользовательского элемента управления.

this.DataContext = this;

Wpf связывается с текущим контекстом данных, если не был указан конкретный источник (например, ElementName).

Использовать связывание с ElementName

Вы можете ссылаться на пользовательский элемент управления в выражениях привязки.

<UserControl x:Class="WpfApplication1.SubsetSelectionLists"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             x:Name="root">
<Grid>
...
    <ListBox Name="SET"
             ItemsSource="{Binding Path=SetCollection, ElementName=root}" />
...
    <ListBox Name="SUBSET" Grid.Column="2"
             ItemsSource="{Binding Path=SubsetCollection, ElementName=root}" />

</Grid>
</UserControl>

Привязка к ВМ

Другим способом было бы установить контекст данных пользовательского элемента управления в SomeWindow и привязать его к свойствам виртуальной машины. Затем вы можете удалить свойства зависимостей пользовательского элемента управления.

public partial class SomeWindow : Window
{
    ViewModel vm = new ViewModel();
    //with properties InputView and OutputView

    public SomeWindow()
    {
        InitializeComponent();
        NameOfUserControl.DataContext = vm;
    }
}

В пользовательском управлении:

<Grid>
...
    <ListBox Name="SET"
             ItemsSource="{Binding Path=InputView}" />
...
    <ListBox Name="SUBSET" Grid.Column="2"
             ItemsSource="{Binding Path=OutputView}" />

</Grid>
...