【发布时间】:2021-05-19 06:59:18
【问题描述】:
我有一个从默认 TextBox 继承的自定义文本框控件。在样式上,我添加了一些额外的 xaml,其中之一就是这个进度环:
<toolkit:Loading x:Name="IsBusyLoader"
Grid.Column="1"
Grid.ColumnSpan="2"
Style="{StaticResource DefaultLoader}">
<ProgressRing Style="{StaticResource SmallRing}" />
</toolkit:Loading>
我必须通过使用控件的绑定来控制它的“IsLoading”。为此,我在此控件后面的代码中创建了它的绑定,因为它是一种样式,所以我不确定如何使用依赖属性以 xaml 样式创建该绑定。
public FluentTextBox() => DefaultStyleKey = typeof(FluentTextBox);
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
//GetTemplateChild
_isBusyLoader = GetTemplateChild("IsBusyLoader") as Loading;
//bindings
_isBusyLoader.SetBinding(Microsoft.Toolkit.Uwp.UI.Controls.Loading.IsLoadingProperty, new Binding { Mode = BindingMode.OneWay, Source = IsBusy });
}
public bool IsBusy
{
get => (bool) GetValue(IsBusyProperty);
set => SetValue(IsBusyProperty, value);
}
public static readonly DependencyProperty IsBusyProperty =
DependencyProperty.Register("IsBusy", typeof(bool), typeof(FluentTextBox), new PropertyMetadata(null));
如您所见,IsBusy 是一个依赖属性。我在 UI 上绑定到它,我正在使用这个自定义文本框。
<controls1:FluentTextBox
Margin="4"
Header="Field 1"
IsBusy="{x:Bind IsBusy, Mode=OneWay}" />
现在这里的 IsBusy 属性实际上在代码中,问题是当我从后面的代码更新 IsBusy 属性时,它不会反映在 UI 中。但是我在该页面的其他地方使用了相同的 IsBusy 属性,并且它在那里正确地向 UI 发出通知,所以我很清楚该部分工作正常。
public bool IsBusy // code behind is busy property on my xaml page.
{
get => _isBusy;
set
{
_isBusy = value;
RaisePropertyChanged(nameof(IsBusy));
}
}
请注意,当我在源代码中创建绑定并将其设置为“true”时,我的自定义文本框会按预期显示进度环。我也尝试将源绑定到 IsBusyProperty ,但这也不起作用。
_isBusyLoader.SetBinding(Microsoft.Toolkit.Uwp.UI.Controls.Loading.IsLoadingProperty, new Binding { Mode = BindingMode.OneWay, Source = true });
更新 1
完整样式代码
<Style TargetType="controls:FluentTextBox">
<Setter Property="Margin" Value="{ThemeResource DefaultControlMargin}" />
<Setter Property="local:TextBoxProperties.Initialized" Value="true" />
<Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}" />
<Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}" />
<Setter Property="Foreground" Value="{ThemeResource TextControlForeground}" />
<Setter Property="Background" Value="{ThemeResource TextControlBackground}" />
<Setter Property="BorderBrush" Value="{ThemeResource TextControlBorderBrush}" />
<Setter Property="SelectionHighlightColor" Value="{ThemeResource TextControlSelectionHighlightColor}" />
<Setter Property="BorderThickness" Value="{ThemeResource TextControlBorderThemeThickness}" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource InputControlFontSize}" />
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
<Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
<Setter Property="HorizontalAlignment" Value="{ThemeResource DefaultControlHorizontalAlignment}" />
<Setter Property="VerticalAlignment" Value="{ThemeResource DefaultControlVerticalAlignment}" />
<Setter Property="Padding" Value="{ThemeResource TextControlThemePadding}" />
<Setter Property="UseSystemFocusVisuals" Value="{ThemeResource IsApplicationFocusVisualKindReveal}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:FluentTextBox">
<Grid>
<Grid.Resources>
<!--default delete button style here-->
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<i:Interaction.Behaviors>
<ic:EventTriggerBehavior EventName="PointerEntered">
<ic:CallMethodAction MethodName="StartAnimation" TargetObject="{Binding ElementName=MoreActionGridFadeIn}" />
</ic:EventTriggerBehavior>
<ic:EventTriggerBehavior EventName="PointerExited">
<ic:CallMethodAction MethodName="StartAnimation" TargetObject="{Binding ElementName=MoreActionGridFadeOut}" />
</ic:EventTriggerBehavior>
</i:Interaction.Behaviors>
<Border
x:Name="BorderElement"
Grid.Row="0"
Grid.RowSpan="3"
Grid.ColumnSpan="2"
MinWidth="{ThemeResource TextControlThemeMinWidth}"
MinHeight="{ThemeResource TextControlThemeMinHeight}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Control.IsTemplateFocusTarget="True"
CornerRadius="{TemplateBinding CornerRadius}" />
<Border
x:Name="ValidationBorder"
Grid.Row="0"
Grid.RowSpan="3"
Grid.ColumnSpan="2"
MinWidth="{ThemeResource TextControlThemeMinWidth}"
MinHeight="{ThemeResource TextControlThemeMinHeight}"
BorderBrush="{ThemeResource ValidationBorderBrush}"
CornerRadius="{TemplateBinding CornerRadius}" />
<ContentPresenter
x:Name="ShadowHeaderContentPresenter"
Padding="10,0,2,0"
Background="{x:Null}"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
FontSize="{TemplateBinding FontSize}"
FontWeight="Normal"
Foreground="{x:Null}"
Opacity="0"
TextWrapping="NoWrap"
Visibility="Visible" />
<ContentPresenter
x:Name="HeaderContentPresenter"
Padding="10,0,2,0"
x:DeferLoadStrategy="Lazy"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
FontSize="{TemplateBinding FontSize}"
FontWeight="Normal"
Foreground="{Binding ElementName=PlaceholderTextContentPresenter, Path=Foreground, Mode=OneWay}"
TextWrapping="NoWrap"
Visibility="Collapsed">
<ContentPresenter.RenderTransform>
<CompositeTransform />
</ContentPresenter.RenderTransform>
</ContentPresenter>
<ScrollViewer
x:Name="ContentElement"
Grid.Row="1"
Margin="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
AutomationProperties.AccessibilityView="Raw"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
IsTabStop="False"
IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
ZoomMode="Disabled" />
<TextBlock
x:Name="PlaceholderTextContentPresenter"
Grid.Row="1"
Grid.ColumnSpan="2"
Margin="{TemplateBinding BorderThickness}"
Padding="10,0,0,0"
Foreground="{Binding PlaceholderForeground, RelativeSource={RelativeSource TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForeground}}"
IsHitTestVisible="False"
Text="{TemplateBinding PlaceholderText}"
TextAlignment="{TemplateBinding TextAlignment}"
TextWrapping="{TemplateBinding TextWrapping}" />
<Grid Grid.RowSpan="3" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button
x:Name="DeleteButton"
MinWidth="{ThemeResource DeleteButtonMinWidth}"
MaxWidth="{ThemeResource DeleteButtonMaxWidth}"
Margin="{ThemeResource HelperButtonThemePadding}"
VerticalAlignment="Stretch"
AutomationProperties.AccessibilityView="Raw"
BorderThickness="{TemplateBinding BorderThickness}"
FontSize="{TemplateBinding FontSize}"
IsTabStop="False"
Style="{StaticResource DeleteButtonStyle}"
Visibility="Collapsed" />
<Grid x:Name="ActionGrid" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition Width="48" />
</Grid.ColumnDefinitions>
<Grid>
<Grid x:Name="MoreGrid" Opacity="0">
<i:Interaction.Behaviors>
<ToolkitBehaviors:Fade
x:Name="MoreActionGridFadeIn"
AutomaticallyStart="False"
Delay="0"
EasingMode="EaseOut"
EasingType="Cubic"
Value="1"
Duration="300" />
<ToolkitBehaviors:Fade
x:Name="MoreActionGridFadeOut"
AutomaticallyStart="False"
Delay="0"
EasingMode="EaseOut"
EasingType="Cubic"
Value="0"
Duration="300" />
</i:Interaction.Behaviors>
<AppBarButton
x:Name="CopyButton"
Width="48"
Height="48"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Icon="Copy"
ToolTipService.ToolTip="Copy" />
</Grid>
</Grid>
<Grid Grid.Column="1">
<toolkit:DropShadowPanel
Width="24"
Height="24"
Margin="8"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Style="{StaticResource GridShadowSmall}"
Color="Black">
<Ellipse
Width="24"
Height="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="{TemplateBinding BorderBrush}" />
</toolkit:DropShadowPanel>
<Ellipse
x:Name="CentralElipse"
Width="20"
Height="20"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Canvas.ZIndex="10">
<ToolTipService.ToolTip>
<ToolTip>
<Grid Width="140" MaxHeight="200">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock
x:Name="MemosCountBlock"
Grid.Row="1"
Margin="4"
FontWeight="SemiBold"
TextTrimming="CharacterEllipsis"
TextWrapping="Wrap" />
<TextBlock
Grid.Row="1"
Grid.Column="1"
Margin="4"
Text="Memos"
TextTrimming="CharacterEllipsis"
TextWrapping="WrapWholeWords" />
<TextBlock
x:Name="MyFirstMemoBlock"
Grid.ColumnSpan="2"
Margin="4"
TextTrimming="CharacterEllipsis"
TextWrapping="WrapWholeWords" />
</Grid>
</ToolTip>
</ToolTipService.ToolTip>
<FlyoutBase.AttachedFlyout>
<Flyout x:Name="MemosFlyout" FlyoutPresenterStyle="{StaticResource NoPaddingFlyoutPresenter}">
<local1:MemosControl
x:Name="MyMemosControl"
Width="320"
MaxHeight="440"
Padding="0,8,0,0"
NewMemoButtonVisible="True" />
</Flyout>
</FlyoutBase.AttachedFlyout>
</Ellipse>
</Grid>
<toolkit:Loading
x:Name="IsBusyLoader"
Grid.ColumnSpan="2"
Style="{StaticResource DefaultLoader}">
<ProgressRing Style="{StaticResource SmallRing}" />
</toolkit:Loading>
</Grid>
</Grid>
<ContentPresenter
x:Name="DescriptionPresenter"
Grid.Row="2"
Padding="10,0,4,4"
x:Load="False"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding Description}"
FontSize="{StaticResource InputControlHeaderFontSize}"
Foreground="{Binding ElementName=PlaceholderTextContentPresenter, Path=Foreground, Mode=OneWay}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Disabled">
<!-- default disabled state -->
</VisualState>
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<!-- default pointer over state -->
</VisualState>
<VisualState x:Name="Focused">
<!-- default focused state -->
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ButtonStates">
<VisualState x:Name="ButtonVisible">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="DeleteButton" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="ButtonCollapsed" />
</VisualStateGroup>
<VisualStateGroup x:Name="HeaderStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.25">
<VisualTransition.GeneratedEasingFunction>
<CircleEase EasingMode="EaseInOut" />
</VisualTransition.GeneratedEasingFunction>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="NotEmpty">
<VisualState.Setters>
<Setter Target="HeaderContentPresenter.(FontSize)" Value="{StaticResource InputControlHeaderFontSize}" />
</VisualState.Setters>
<VisualState.StateTriggers>
<StateTrigger IsActive="{Binding Text, Converter={StaticResource IsNotEmptyConverter}, Mode=OneWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
</VisualState.StateTriggers>
</VisualState>
<VisualState x:Name="Empty">
<VisualState.Setters>
<Setter Target="HeaderContentPresenter.(UIElement.RenderTransform).(CompositeTransform.TranslateY)" Value="16" />
<Setter Target="PlaceholderTextContentPresenter.(Opacity)" Value="0" />
</VisualState.Setters>
<VisualState.StateTriggers>
<StateTrigger IsActive="{Binding Text, Converter={StaticResource IsEmptyConverter}, Mode=OneWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ValidationStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.25">
<VisualTransition.GeneratedEasingFunction>
<CircleEase EasingMode="EaseInOut" />
</VisualTransition.GeneratedEasingFunction>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Valid" />
<VisualState x:Name="NotValid">
<VisualState.Setters>
<Setter Target="ValidationBorder.(BorderThickness)" Value="{ThemeResource ValidationBorderThickness}" />
</VisualState.Setters>
<VisualState.StateTriggers>
<StateTrigger IsActive="{Binding (local:Validation.HasError), Mode=OneWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" />
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
【问题讨论】:
-
您能否为您的
FluentTextBox控件发布Style,包括模板? -
@mm8 添加。我已经删除了一些无关紧要的代码,因为它超出了这里的字符限制,并且我已经评论了我删除代码的地方,它的大部分是默认代码,所以不会很重要
标签: c# xaml uwp binding styles