【问题标题】:Can't get Text value from Control Template无法从控制模板中获取文本值
【发布时间】:2012-06-17 09:20:43
【问题描述】:

我使用控件模板重新设置了文本框的样式。样式效果很好,但在文本框中更改后,我现在无法以编程方式从文本框中获取文本值。

这是我使用样式的方式:

     <TextBox
        x:Name="KernTextBox"
        Style="{StaticResource MediumTextBoxStyle}"
        TextWrapping="Wrap"
        MinLines="1"
        MaxLines="5"
        VerticalScrollBarVisibility="Auto"
        TextChanged="TextChanged"
        />

这是行不通的。

  get { return KernTextBox.Text; }

风格如下:

<Style x:Key="MediumTextBoxStyle" TargetType="TextBox">
    <Setter Property="FontSize" Value="18" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TextBox">
                <Grid>

                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver" />
                            <VisualState x:Name="ReadOnly">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="ButtonRectangle"
                                        Storyboard.TargetProperty="Fill">
                                        <DiscreteObjectKeyFrame
                                            KeyTime="0"
                                            Value="{StaticResource ForegroundBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="ButtonText"
                                        Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame
                                            KeyTime="0"
                                            Value="{StaticResource BackgroundBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="ButtonText"
                                        Storyboard.TargetProperty="Background">
                                        <DiscreteObjectKeyFrame
                                            KeyTime="0"
                                            Value="{StaticResource ForegroundBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="ButtonText"
                                        Storyboard.TargetProperty="BorderBrush">
                                        <DiscreteObjectKeyFrame
                                            KeyTime="0"
                                            Value="{StaticResource ForegroundBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="ButtonRectangle"
                                        Storyboard.TargetProperty="Fill">
                                        <DiscreteObjectKeyFrame
                                            KeyTime="0"
                                            Value="{StaticResource ForegroundBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="ButtonText"
                                        Storyboard.TargetProperty="Foreground">
                                        <DiscreteObjectKeyFrame
                                            KeyTime="0"
                                            Value="{StaticResource BackgroundBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="ButtonText"
                                        Storyboard.TargetProperty="Background">
                                        <DiscreteObjectKeyFrame
                                            KeyTime="0"
                                            Value="{StaticResource ForegroundBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames
                                        Storyboard.TargetName="ButtonText"
                                        Storyboard.TargetProperty="BorderBrush">
                                        <DiscreteObjectKeyFrame
                                            KeyTime="0"
                                            Value="{StaticResource ForegroundBrush}" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>

                        </VisualStateGroup>

                        <VisualStateGroup x:Name="CheckStates">
                            <VisualState x:Name="Checked" />
                            <VisualState x:Name="Unchecked"/>
                        </VisualStateGroup>

                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused" />
                            <VisualState x:Name="Unfocused"/>
                        </VisualStateGroup>

                    </VisualStateManager.VisualStateGroups>

                    <Rectangle 
                        x:Name="ButtonRectangle" 
                        Stroke="Transparent" 
                        UseLayoutRounding="False" 
                        Fill="{StaticResource BackgroundBrush}">
                    </Rectangle>

                    <TextBox 
                        x:Name="ButtonText" 
                        Text="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                        FontSize="{TemplateBinding FontSize}"
                        HorizontalAlignment="Stretch" 
                        VerticalAlignment="Center" 
                        Margin="2 0"
                        TextWrapping="{TemplateBinding TextWrapping}"
                        MinLines="{TemplateBinding MinLines}"
                        MaxLines="{TemplateBinding MaxLines}"
                        VerticalScrollBarVisibility="{TemplateBinding VerticalScrollBarVisibility}"
                        Padding="{TemplateBinding Padding}"
                        Foreground="{StaticResource ForegroundBrush}"
                        Background="{StaticResource BackgroundBrush}"
                        >
                    </TextBox>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

编辑:

最终的工作方式:

<Style 
    x:Key="TextBoxStyle" 
    TargetType="{x:Type TextBox}">
    <Setter
        Property="Foreground"
        Value="{StaticResource ForegroundBrush}" />
    <Setter
        Property="FontSize"
        Value="18" />
    <Setter 
        Property="CaretBrush"
        Value="{StaticResource ForegroundBrush}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Border 
                    Name="Border"
                    Background="{StaticResource BackgroundBrush}"
                    BorderBrush="{StaticResource ForegroundBrush}"
                    BorderThickness="1" >
                    <ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="Border" Property="Background" Value="{StaticResource ForegroundBrush}"/>
                        <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource BackgroundBrush}"/>
                        <Setter Property="Foreground" Value="{StaticResource BackgroundBrush}"/>
                    </Trigger>
                    <Trigger Property="IsReadOnly" Value="True">
                        <Setter TargetName="Border" Property="Background" Value="{StaticResource ForegroundBrush}"/>
                        <Setter TargetName="Border" Property="BorderBrush" Value="{StaticResource BackgroundBrush}"/>
                        <Setter Property="Foreground" Value="{StaticResource BackgroundBrush}"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

【问题讨论】:

    标签: wpf controltemplate


    【解决方案1】:

    将文本框放在文本框内有什么原因吗?签出文本框的原始样式和 template 并从那里进行修改。我的猜测是,文本框在内部使用 TextBoxView(隐藏在 Scrollviewer 中),并且 Text 属性不是通过 TemplateBinding 绑定的,而是在这些内部类之间计算的。所以也许这就是为什么你不能将你的文本属性绑定到你的控件模板中的文本框文本的原因。

    【讨论】:

    • 如果我想为每个文本框设置样式,但又不必设置完整的文本框,我也将完全按照此处所做的操作。
    • @Andy 好吧,仍然不是一个好主意。用户控件怎么样?或者,直接拿原来的样式修改一下,普通的文本框控件模板就很短了。但是在文本框中放置一个文本框是一个非常奇怪的“hack”恕我直言。
    • 我听取了您的建议并重新编写了样式以删除文本框。现在都在工作。我已将样式添加到我的问题中。
    【解决方案2】:

    在您的样式中,当您将内部 Text 属性绑定到 Template Text 属性时,添加更新源触发器 PropertyChanged ,然后即使您没有失去焦点,您也会获得文本更新。

    Text="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
    

    您设置文本框样式的方法不太有效的原因是,默认情况下,文本属性不会更新它的绑定属性,直到从控件中移除焦点。我猜您正在尝试使用 TextChanged 事件中的 Text 属性,此时该属性尚未从 TextBox 中移除焦点。

    我建议对您的 Text 绑定的添加将强制属性在每次文本更改时更新,并且会在引发 TextChanged 事件之前进行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多