开发者

WPF: Need some help binding into UserControl

I'm trying to build a UserControl which includes 2 listBoxes. I then wan't to set the itemsSources for the listboxes where I use the UserControl.

As I understand that is what DependencyProperties are for. However I'm not successful in doing this. I do believe it mostly has to do with the timing of initialization. Any pointer on what I'm doing right, how I can make it better and such is welcome.

Here is my user control, I'm learning as I'm going so I guess I could do it better

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

And the code behind where I use it

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

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

Here the SetCollection is set as inputView and then later tied to the DependencyProperty severing the original binding I think. Any idea where I'm going wrong?

Ps. subquestion - As I will be moving from one collection to the other shouldn't I ensure somehow that the collection hold objects off the same type? How could I do that?


First of all you should set the DataContext property in SomeWindow to vm. This will allow very simple binding expression in your SomeWindow.xaml.

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

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

In SomeWindow.xaml:

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

There are several ways to solve the binding problem in the user control:

Setting the data context

Add the following to the constructor of the user control.

this.DataContext = this;

Wpf binds against the current data context, unless a specific source (e.g. ElementName) has been set.

Use binding with ElementName

You could reference the user control in the binding expressions.

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

Bind to the VM

Another method would be to set the data context of the user control in SomeWindow and bind to the Properties of the VM. You could then remove the dependency properties of the user control.

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

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

In the user control:

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

</Grid>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜