Search code examples
c#mvvmavaloniauiavalonia

DataTemplate bound items not changing with bound content


I have a set of tabs I'm displaying in an Avalonia TabControl, each represented by a TabModel object.

TabModel.cs:

public class TabModel
{
    public string Name { get; set; }
    public string Content { get; set; }
}

I want each tab to have a TextBlock as its title (similar to the example from the docs) and a custom control as the body. When loading the TabControl, the titles and body display properly. However, when I modify the Name or Content fields, the controls won't update. When Content is changed by the control (through the TwoWay binding), the change is reflected in the field and any changes made by the code are forgotten.

Xaml:

<TabControl Items="{Binding Tabs}">

    <TabControl.ItemTemplate>
        <TreeDataTemplate DataType="models:TabModel">
            <TextBlock Text="{Binding Name}" />
        </TreeDataTemplate>
    </TabControl.ItemTemplate>

    <TabControl.ContentTemplate>
        <TreeDataTemplate DataType="models:TabModel">
            <controls:BoundEditor
                BoundText="{Binding Content, Mode=TwoWay}" Name="BoundEditor" />
        </TreeDataTemplate>
    </TabControl.ContentTemplate>

</TabControl>


Solution

  • At the moment, your model is a plain POCO. Plain Old CLR Object.

    What you need is a ViewModel ...

    public class TabModel : ReactiveObject
    {
        private string _name;
    
        public string Name 
        {
            get { return _name; }
            set { this.RaiseAndSetIfChanged(ref _name, value); }
        }
        ...
    }
    

    Now every time the Name setter is called, it will check to see if the value is new, update it if it is, and then will notify UI to update.