WPF自定义TextBox

时间:2013-12-16 15:50:01

标签: wpf xaml textbox

我有一个名为“txtAddress”的自定义TextBox,其中包含ImageTextBox
我需要能够访问其内容:txtAddress.Text txtAddress.Image
我已将inner textBox.textTemplate.Text绑定,inner rect.FillTemplate.Background绑定(我现在使用矩形,我会将其更改为图像)

enter image description here

当我运行程序并编辑textBox时,一切看起来都在工作,文本正在改变,但是当我从代码txtAddress.Text使用它时仍然是“我的计算机”,这是的初始值的TextBox。 我知道因为我没有把<ContentPresenter>放在风格的某个地方,但我应该把控件(图像,文本框)放在哪里,就像在listView中有<DataTemplate>我们添加控件

TxtAddress风格:

<Style x:Key="TextBoxAddressStyle" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
        <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Padding" Value="1"/>
        <Setter Property="AllowDrop" Value="true"/>
        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
        <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Grid HorizontalAlignment="Stretch" Height="Auto" VerticalAlignment="Stretch" Width="Auto">
                        <Rectangle Height="Auto" Stroke="{TemplateBinding Foreground}" VerticalAlignment="Stretch" RadiusY="11" RadiusX="11" Margin="0" Fill="{TemplateBinding OpacityMask}"/>
                        <!--<ContentPresenter Height="Auto" Margin="31,2,7.458,2"/>-->
                        <TextBox x:Name="TxtAddress" Height="Auto" Margin="31,2,7.458,2" VerticalAlignment="Stretch" MaxLines="1" Text="{TemplateBinding Text}" AcceptsTab="True" Style="{DynamicResource TextBoxStyle2}" SelectionBrush="#C859003D" FontSize="{TemplateBinding FontSize}" AcceptsReturn="False"/>
                        <Rectangle Fill="#5AFFFFFF" HorizontalAlignment="Stretch" Height="6.375" Margin="6,2.25,6,0" RadiusY="6" RadiusX="6" Stroke="{x:Null}" VerticalAlignment="Top" Width="Auto" d:IsLocked="True"/>
                        <Rectangle x:Name="ImgAddress" Fill="{TemplateBinding Background}" HorizontalAlignment="Left" Height="24" Margin="7,1,0,0" RadiusY="0" RadiusX="0" VerticalAlignment="Top" Width="24" StrokeThickness="0">
                            <Rectangle.Stroke>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="Black" Offset="1"/>
                                    <GradientStop Color="White"/>
                                </LinearGradientBrush>
                            </Rectangle.Stroke>
                        </Rectangle>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
                    <Condition Property="IsSelectionActive" Value="false"/>
                </MultiTrigger.Conditions>
                <Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
            </MultiTrigger>
        </Style.Triggers>
    </Style>

内部文本框样式:

<Style x:Key="TextBoxStyle2" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
        <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/>
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Padding" Value="1"/>
        <Setter Property="AllowDrop" Value="true"/>
        <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
        <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
        <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" FontSize="13.333" PanningMode="HorizontalOnly"/>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="false">
                            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
                    <Condition Property="IsSelectionActive" Value="false"/>
                </MultiTrigger.Conditions>
                <Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
            </MultiTrigger>
        </Style.Triggers>
    </Style>

TxtAddress:

 <TextBox x:Name="txtAddress" Margin="34,5,32,0" TextWrapping="Wrap" Text="My Computer" Style="{DynamicResource TextBoxAddressStyle}" Height="25" VerticalAlignment="Top" FontWeight="Bold" MinHeight="25" MaxHeight="25">
            <TextBox.Background>
                <ImageBrush ImageSource="BtnImg/computer.png" Stretch="None"/>
            </TextBox.Background>
            <TextBox.Foreground>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF779198" Offset="0.1"/>
                    <GradientStop Color="#FF789399" Offset="0.93"/>
                    <GradientStop Color="#FFBFD3D7" Offset="0.513"/>
                    <GradientStop Color="#FF343E41" Offset="1"/>
                    <GradientStop Color="#FF5C6E73"/>
                </LinearGradientBrush>
            </TextBox.Foreground>
            <TextBox.OpacityMask>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF94B5BD" Offset="0.1"/>
                    <GradientStop Color="#FF94B5BD" Offset="0.93"/>
                    <GradientStop Color="#FFE7FBFF" Offset="0.513"/>
                    <GradientStop Color="#FF7B9399" Offset="1"/>
                    <GradientStop Color="#FF7B9399"/>
                </LinearGradientBrush>
            </TextBox.OpacityMask>
        </TextBox>

提前感谢。

1 个答案:

答案 0 :(得分:0)

您在另一个TextBox的模板中放置了TextBox

可视树将如下所示:

TextBox
   Grid
      Rectangle 
      TextBox
      Rectangle 
      Rectangle

首先这不是理想的,但是如果你想保留这样的东西,只需确保通过Two Way {UpdateSourceTrigger=PropertyChanged确保将内部TextBox的Text属性绑定到外部属性。 3}}数据绑定如下:

<TextBox x:Name="TxtAddress" Text="{Binding Text, 
                                            Mode=TwoWay, 
                                            UpdateSourceTrigger=PropertyChanged,  
                                            RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}" ... />

除此之外,我已经多次提到你不应该在WPF中的过程代码中操作UI元素。

相反,请创建一个适当的ViewModel来存储您的数据:

public class MyViewModel
{
    public string Text {get;set;}
}

然后使用DataBinding将TextBox绑定到该数据:

<TextBox Text="{Binding Text}"/>

无论何时需要检索值,都要从VM中检索值,而不是UI。