TextBox的样式:为什么' AcceptsReturn = true'没有申请?

时间:2014-11-03 18:24:47

标签: wpf xaml styles custom-controls

我在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都包含在样式中。

TextWrappingVerticalScrollBarVisibility都设置正确:

VSV

AcceptsReturn不是:

ACR

任何想法,这可能是什么问题?

1 个答案:

答案 0 :(得分:1)

您发布的屏幕截图显示AcceptsReturn具有本地值,即通过显式调用属性设置器或SetValue设置的值。你有EditableLabel中明确设置AcceptsReturn属性的代码吗?如果是这样,您设置的本地值将优先于任何样式设置器。您可以使用SetCurrentValue更改值,同时保持值源不变,从而避免这种情况。

其次,在代码中分配样式后,简单地在模板中绑定样式通常更容易,更可靠,例如:

<TextBox x:Name="PART_TextBox" Style="{TemplateBinding TextBoxStyle}" ... />

你可以先尝试一下,看看你是否会得到更好的结果。