0

I have a strange Data-Binding issue in WPF on .Net Core 3.1 on Windows 10.

I have a Person Model:

public class Person
{
    public long Id { get; set; }
    public string Name { get; set; }
    public long? CityId { get; set; }
}

and a City model like this:

public class City
{
    public long Id { get; set; }
    public long ZipCode { get; set; }
    public string Name { get; set; }
}

I have an ItemsControl like this:

<ItemsControl Margin="10" ItemsSource="{Binding People}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Margin="5" Text="{Binding Id}" />
                <TextBlock Margin="5" Text="{Binding Name}" />
                <local:CityView
                    Margin="5"
                    CityId="{Binding CityId}"
                    CityList="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext.CityList}" />
            </StackPanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

And I have a CityView Usercontrol:

<UserControl
x:Class="WpfIssues.CityView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Orientation="Vertical">
    <ComboBox
        DisplayMemberPath="Name"
        ItemsSource="{Binding CityList}"
        SelectedValue="{Binding CityId}"
        SelectedValuePath="Id" />
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="CityId from UserControl CityId PropDp: " />
        <TextBlock FontWeight="Bold" Text="{Binding CityId}" />
    </StackPanel>
</StackPanel>

This usercontrol has 2 PropDp:

    public long CityId
    {
        get { return (long)GetValue(CityIdProperty); }
        set { SetValue(CityIdProperty, value); }
    }

    public static readonly DependencyProperty CityIdProperty =
        DependencyProperty.Register("CityId", typeof(long), typeof(CityView));

    public List<City> CityList
    {
        get { return (List<City>)GetValue(CityListProperty); }
        set { SetValue(CityListProperty, value); }
    }

    public static readonly DependencyProperty CityListProperty =
        DependencyProperty.Register("CityList", typeof(List<City>), typeof(CityView));

And I have a ViewModel that is used by the Window containing the ItemsControl:

    public List<Person> People { get; set; }
    public List<City> CityList { get; set; }

    public ViewModel()
    {
        People = new List<Person> { new Person {Id = 1, Name = "Thomas", CityId = 1}};
        CityList = new List<City> { new City { Id = 1, Name = "Copenhagen" }};
    }

My issue is that the CityId="{Binding CityId}" from the Person class is not bound to the CityId PropDp in the CityView usercontrol eventhough the ItemsControls ItemSource is List<Person> and Person class has a public long? CityId { get; set; }

If I do CityId="1" then the CityView Usercontrol shows the value 1 for the CityId Propdp

ThomasE
  • 369
  • 1
  • 5
  • 19
  • 2
    The UserControl seems to set its own DataContext, which would break `CityId="{Binding CityId}"`. See e.g. here: https://stackoverflow.com/a/28982771/1136211 – Clemens Feb 24 '21 at 13:53
  • Hi Clemens - you're right, the linked answer solved my issue: In the UserControl I did this: ItemsSource="{Binding CityList, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" And then don't set the DataContext in the CTOR on the CityView usercontrol – ThomasE Feb 24 '21 at 14:04
  • If you had used different names for the UserControl and view model properties, you would have observed a data binding error message in the Output Window in Visual Studio. – Clemens Feb 24 '21 at 14:05
  • Okay - in my real-life app - I did get this binding error message. – ThomasE Feb 24 '21 at 14:07

0 Answers0