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.