Search code examples
c#xamldata-bindingwinui-3winui

Binding Header Text In A Custom Header Template


I am having an issue binding header in a HeaderTemplate. When I do the following in xaml, this textblock either doesn't appear or there is no text shown in it making it invisible:

<TextBlock Text="{Binding}" Foreground="Red" HorizontalAlignment="Left" />

When working correctly it should show the header text which would be: "Name".

Xaml

<TextBox x:Name="NameTextBox" Header="Name" PlaceholderText="Enter Name" PlaceholderForeground="Gray"  IsColorFontEnabled="True" Text="{x:Bind ViewModel.Supplier.Name, Mode=TwoWay}">
    <TextBox.HeaderTemplate >
        <DataTemplate x:DataType="models:Supplier">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding}" Foreground="Red" HorizontalAlignment="Left" />
            <SymbolIcon Symbol="ReportHacked" Foreground="Red" Visibility="{x:Bind HasErrors, Mode=OneWay}" HorizontalAlignment="Right" Margin="0 4">
                <ToolTipService.ToolTip>
                    <TextBlock Text="{x:Bind Errors, Mode=OneWay}" Foreground="Red" />
                </ToolTipService.ToolTip>
            </SymbolIcon>
            </StackPanel>
        </DataTemplate>
    </TextBox.HeaderTemplate>
</TextBox>

View Model

public partial class SupplierViewModel: ObservableValidator
{
    RecipeDBContext context;

    private Supplier _supplier = new Supplier();
    public Supplier Supplier => _supplier;

    [ObservableProperty]
    private ObservableCollection<Supplier> _suppliers;
}

Model

public partial class Supplier: ObservableValidator
{
    public int Id { get; set; }
    
    [ObservableProperty]
    [NotifyDataErrorInfo]
    [Required(ErrorMessage = "Name is Required")]
    [MinLength(2, ErrorMessage = "Name should be longer than one character")]
    private string _name = string.Empty;            
}

Solution

  • You are passing a string "Name" as the Header. If you want to have access to the Supplier value, you need to pass it to the Header:

    <TextBox
        x:Name="NameTextBox"
        Header="{x:Bind ViewModel.Supplier.Name, Mode=OneWay}"
        Text="{x:Bind ViewModel.Supplier.Name, Mode=TwoWay}"
        ...>
        <TextBox.HeaderTemplate>
            <DataTemplate x:DataType="models:Supplier">
            </DataTemplate>
        </TextBox.HeaderTemplate>
    </TextBox>