我在WPF中有一个自定义控件,它由一个切换按钮,一个TextBlock和一个TextBox组成。我基本上想要做的是在选中切换按钮时显示TextBox,否则显示TextBlock。此外,我希望允许通过依赖项属性定义控件上的样式属性,这些属性在运行时应用于TextBlock和TextBox。默认模板如下所示:
<Style TargetType="{x:Type views:EditableLabel}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type views:EditableLabel}">
<Border Background="{TemplateBinding Background}">
<DockPanel Margin="0">
<telerik:RadToggleButton x:Name="PART_Toggle"
DockPanel.Dock="Right"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsInEditMode, Mode=TwoWay}">
<Image Source="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ToggleImage}" Height="14" />
</telerik:RadToggleButton>
<TextBlock x:Name="PART_TextBlock"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text}" >
</TextBlock>
<TextBox x:Name="PART_TextBox"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
</TextBox>
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
自定义控件有两个样式的依赖项属性,一个用于PART_TextBlock
,另一个用于PART_TextBox
。样式在自定义控件的OnApplyTemplate
方法和两个依赖项属性的属性更改回调中分配:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_textBlock = (TextBlock) GetTemplateChild("PART_TextBlock");
_textBox = (TextBox) GetTemplateChild("PART_TextBox");
_toggleButton = (RadToggleButton) GetTemplateChild("PART_Toggle");
ApplyStyles();
UpdateVisibilities();
}
private void ApplyStyles()
{
if (_textBlock != null) _textBlock.Style = TextBlockStyle;
if (_textBox != null) _textBox.Style = TextBoxStyle;
}
(这里没有显示回调,因为它们很简单,只需拨打ApplyStyles()
。
我使用这样的自定义控件:
<views:EditableLabel Text="{Binding SelectedToolbox.Description, Mode=TwoWay}"
CanEdit="{Binding SelectedToolbox.CanEdit}"
ToggleImage="../Resources/Images/edit-26.png">
<views:EditableLabel.TextBlockStyle>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap" />
</Style>
</views:EditableLabel.TextBlockStyle>
<views:EditableLabel.TextBoxStyle>
<Style TargetType="TextBox">
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="AcceptsReturn" Value="True" />
<Setter Property="VerticalScrollBarVisibility" Value="Visible" />
</Style>
</views:EditableLabel.TextBoxStyle>
</views:EditableLabel>
一切都按预期工作,除了AcceptsReturn
setter没有应用,我觉得很奇怪。我已调试ApplyStyles()
:正确分配了样式,并且两个setter都包含在样式中。
TextWrapping
和VerticalScrollBarVisibility
都设置正确:
而AcceptsReturn
不是:
任何想法,这可能是什么问题?
答案 0 :(得分:1)
您发布的屏幕截图显示AcceptsReturn
具有本地值,即通过显式调用属性设置器或SetValue
设置的值。你有EditableLabel
中明确设置AcceptsReturn
属性的代码吗?如果是这样,您设置的本地值将优先于任何样式设置器。您可以使用SetCurrentValue
更改值,同时保持值源不变,从而避免这种情况。
其次,在代码中分配样式后,简单地在模板中绑定样式通常更容易,更可靠,例如:
<TextBox x:Name="PART_TextBox" Style="{TemplateBinding TextBoxStyle}" ... />
你可以先尝试一下,看看你是否会得到更好的结果。