Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

TemplateBinding is not updating value on control in TextBox.Inner***Content

Open timunie opened this issue 1 year ago • 1 comments

Discussed in https://github.com/AvaloniaUI/Avalonia/discussions/11891

Originally posted by sn4k3 June 25, 2023 I'm trying to extend the NumericUpDown control to add Left content to it TextBox. If I enter static text it will show, however any TemplateBinding sees no alterations.

Extended NumericUpDown xaml code:

<Styles xmlns="https://github.com/avaloniaui"
		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
		xmlns:controls="clr-namespace:UVtools.WPF.Controls">
	<Design.PreviewWith>
		<Border Padding="20">
			<StackPanel Spacing="20">
				<controls:ResettableNumericUpDown Minimum="0"
                                         Maximum="10"
                                         Increment="0.5"
                                         Width="150"
                                         Watermark="Enter text" />
				<controls:ResettableNumericUpDown Minimum="0"
                                         Maximum="10"
                                         Increment="0.5"
                                         Width="150"
                                         VerticalContentAlignment="Center"
                                         HorizontalContentAlignment="Center"
                                         ButtonSpinnerLocation="Left"
                                         Watermark="Enter text" />
			</StackPanel>
		</Border>
	</Design.PreviewWith>

	<Style Selector="controls|ResettableNumericUpDown">
		<Setter Property="Foreground" Value="{DynamicResource TextControlForeground}" />
		<Setter Property="Background" Value="{DynamicResource TextControlBackground}" />
		<Setter Property="BorderThickness" Value="{DynamicResource TextControlBorderThemeThickness}" />
		<Setter Property="BorderBrush" Value="{DynamicResource TextControlBorderBrush}" />
		<Setter Property="MinHeight" Value="{DynamicResource TextControlThemeMinHeight}" />
		<Setter Property="MinWidth" Value="{DynamicResource TextControlThemeMinWidth}" />
		<Setter Property="FontSize" Value="{DynamicResource ControlContentThemeFontSize}" />
		<Setter Property="Padding" Value="{DynamicResource TextControlThemePadding}" />
		<Setter Property="CornerRadius" Value="{DynamicResource ControlCornerRadius}" />

		<Setter Property="Template">
            <ControlTemplate>
                <Grid ColumnDefinitions="*,Auto">
					
					<ButtonSpinner Grid.Column="0" Name="PART_Spinner"
								   Background="{TemplateBinding Background}"
								   BorderThickness="{TemplateBinding BorderThickness}"
								   BorderBrush="{TemplateBinding BorderBrush}"
								   CornerRadius="{TemplateBinding CornerRadius}"
								   Padding="0"
								   MinWidth="0"
								   HorizontalContentAlignment="Stretch"
								   VerticalContentAlignment="Stretch"
								   AllowSpin="{TemplateBinding AllowSpin}"
								   ShowButtonSpinner="{TemplateBinding ShowButtonSpinner}"
								   DataValidationErrors.Errors="{TemplateBinding (DataValidationErrors.Errors)}"
								   ButtonSpinnerLocation="{TemplateBinding ButtonSpinnerLocation}">
                        <TextBox Name="PART_TextBox"
                                 Background="Transparent"
                                 BorderBrush="Transparent"
                                 Margin="-1"
                                 Padding="{TemplateBinding Padding}"
                                 MinWidth="0"
                                 Foreground="{TemplateBinding Foreground}"
                                 FontSize="{TemplateBinding FontSize}"
                                 Watermark="{TemplateBinding Watermark}"
                                 IsReadOnly="{TemplateBinding IsReadOnly}"
                                 VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                 HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                 Text="{TemplateBinding Text}"
                                 AcceptsReturn="False"
                                 TextWrapping="NoWrap">
                            <TextBox.InnerLeftContent>
                                <TextBox Name="PART_OldValueTextBox"
                                         Background="Transparent"
                                         BorderBrush="Transparent"
                                         Padding="{TemplateBinding Padding}"
                                         MinWidth="0"
                                         Foreground="{TemplateBinding Foreground}"
                                         FontSize="{TemplateBinding FontSize}"
                                         IsEnabled="False"
                                         IsReadOnly="True"
                                         VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                         HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
                                         Text="{TemplateBinding Text}"
                                         ToolTip.Tip="Old value"
                                         AcceptsReturn="False"
                                         TextWrapping="NoWrap" />
							</TextBox.InnerLeftContent>
                        </TextBox>
					</ButtonSpinner>
                </Grid>
			</ControlTemplate>
		</Setter>
	</Style>
</Styles>

Relevant part:

<TextBox.InnerLeftContent>
                                <TextBox Name="PART_OldValueTextBox"
                                         Background="Transparent"
                                         BorderBrush="Transparent"
                                         Padding="{TemplateBinding Padding}"
                                         MinWidth="0"
                                         Foreground="{TemplateBinding Foreground}"
                                         FontSize="{TemplateBinding FontSize}"
                                         IsEnabled="False"
                                         IsReadOnly="True"
                                         VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
                                         HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
------------------------------>          Text="{TemplateBinding Text}" 
                                         ToolTip.Tip="Old value"
                                         AcceptsReturn="False"
                                         TextWrapping="NoWrap" />
							</TextBox.InnerLeftContent>

Results in InnerLeftContent never to update the Text with Text="{TemplateBinding Text}"

image

If I set fixed text, ie: Text="123" it will show image

I believe I'm doing something wrong, but I can't figure out where's the problem

Note: Attaching the debugger on this.GetObservable(TextProperty).Subscribe fires correctly, just to be sure that Text is getting the notification.

EDIT 1: Found a workaround that works: Text="{Binding $parent[controls:ResettableNumericUpDown].Text, Mode=OneWay}" but it looks silly... Actually any binding inside <TextBox.InnerLeftContent>only works with this way, TemplateBinding always null. Why?

timunie avatar Jun 27 '23 09:06 timunie

Look material.avalonia, they have InnerLeft on textbox that works with binding

cesarchefinho avatar Jul 05 '23 15:07 cesarchefinho

The TemplatedParent of the inner control (PART_OldValueTextBox) is not the outer NumericUpDown as expected, but PART_TextBox from within the template.

Looks like a control assigned to InnerLeftContent isn't assigned a templated parent when constructed from a XAML template.

TomEdwardsEnscape avatar Aug 23 '23 08:08 TomEdwardsEnscape