简体   繁体   中英

WPF bind CustomControl's property in ListBox

I have following ListBox in my WPF application:

<ListBox x:Name="Domaci_soupiska" Margin="0" Background="#FFF1DE8A" AllowDrop="True" Drop="Soupiska_D_drop" Grid.Column="1">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Label Content="{Binding Typ, Mode=TwoWay}" />
                <local:HracControl Hrac="{Binding Hrac, Mode=TwoWay}"/>
                <TextBox Text="{Binding Cas, Mode=TwoWay}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

which ItemsSource is ObservableCollection<SoupiskaRow> where the SoupiskaRow is a simple class:

public class SoupiskaRow
{
    public string Typ { get; set; }
    public Hrac Hrac { get; set; }
    public string Cas { get; set; }
}

and the local:HracControl is a UserControl with dependency property Hrac (pretty much just a storage). However when I add an item to the ObervableCollecion only "default" HracControl is created inside the ListBox - without any data set. Moreover, when I put breakpoint to the set part of Hrac dependency property the databinding does not even try to set this property.
The databinding sets the label context or textbox text just fine but I dont understand why it does not even attempt to set a custom property?
I found several threads on similar topic, but they suggested dropping any CustomControls and copy/paste its code into the DataTemplate of ListBox .
Code of HracControl is rather simple:

public Hrac Hrac
    {
        get { return (Hrac)GetValue(HracProperty); }
        set { SetValue(HracProperty, value);}
    }

    public static readonly DependencyProperty HracProperty =
            DependencyProperty.Register("Hrac", typeof(Hrac), typeof(HracControl) , new PropertyMetadata(new Hrac()));

    public HracControl()
    {
        this.InitializeComponent();
        this.DataContext = this;
    }

    public HracControl(Hrac hrac)
    {
        this.InitializeComponent();
        this.Hrac = hrac;
        this.DataContext = this;
    }
//and a methods for reordering/hiding some columns and drag/drop events
}

the inside of xaml:

<Grid x:Name="LayoutRoot">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
...
        </Grid.ColumnDefinitions>
        <Label x:Name="Hrac_ID" Content="{Binding Hrac.Hrac_ID}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
        <Label x:Name="Jmeno" Content="{Binding Hrac.Jmeno}" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="1"/>
...
</Grid>

if you need more code, please let me know in comments

As mentioned in the comment each FrameworkElement can have only one DataContext . It will be either inherited through visual tree or set manually.

public HracControl(Hrac hrac)
{
    ...
    this.DataContext = this;
}

By doing this you change default binding context for control itself and all its children, including

<local:HracControl Hrac="{Binding Hrac....}"/>. 

So it will search Hrac in HracControl , so it will try to bind HracControl.Hrac to HracControl.Hrac . Instead of setting DataContext manually in constructor you need to change binding context per binding either via ElementName or RelativeSource binding.

<UserControl ... x:Name="myControl">
    <Grid ...>
        <Label x:Name="Hrac_ID" Content="{Binding ElementName=myControl, Path=Hrac.Hrac_ID}" ... />
        <Label x:Name="Jmeno" Content="{Binding ElementName=myControl, Path=Hrac.Jmeno}" .../>
    </Grid>
</UserControl>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM