WPF 自定义文本框 [英] WPF customized TextBox

查看:51
本文介绍了WPF 自定义文本框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为txtAddress"的自定义文本框,其中包含 ImageTextBox.
我需要能够访问它的内容:txtAddress.Text txtAddress.Image
我已将 inner textBox.textTemplate.Textinner rect.FillTemplate.Background 绑定> (我现在用的是矩形,我会改成图片)

I have a customized TextBox named "txtAddress" which contains Image and TextBox.
I need to be able to access its contents : txtAddress.Text txtAddress.Image
I've Bound the inner textBox.text with the Template.Text and inner rect.Fill with Template.Background (I'm using rectangular now, i will change it to image)

当我运行程序并编辑文本框时,一切看起来都在正常工作并且文本正在发生变化,但是当我从代码中使用它时 txtAddress.Text 仍然是我的电脑",它是文本框的初始值.我知道这是因为我没有将 放在样式中的某处,但是我应该将控件(图像,文本框)放在哪里,就像在 listView 中有 我们在其中添加控件

when I run the program and edit the textBox everything looks like its working and the text is changing, but when i use it from the code txtAddress.Text is still "my computer" which is the initial value of the TextBox. I know that because i didn't put <ContentPresenter> somewhere in the style but where should i put the controls(image,textbox), like in listView there is <DataTemplate> where we add the controls

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>

文本地址:

 <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>

提前致谢.

推荐答案

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

You're placing a TextBox inside the Template for another TextBox.

视觉树看起来像这样:

TextBox
   Grid
      Rectangle 
      TextBox
      Rectangle 
      Rectangle

这首先并不理想,但如果您想保留这样的东西,只需确保通过 两种方式, UpdateSourceTrigger=PropertyChanged 像这样的数据绑定:

Which is not ideal in the first place, but if you want to keep things like that, just make sure you bind the inner TextBox's Text property to the outer one, via Two Way, UpdateSourceTrigger=PropertyChanged Data Binding like so:

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

<小时>

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


In addition to all this, I already mentioned several times that you're NOT supposed to be manipulating UI elements in procedural code in WPF.

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

Instead, create a proper ViewModel to store your data:

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

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

then use DataBinding to bind your TextBox to that data:

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

每当您需要检索值时,请从 VM 中检索值,而不是从 UI 中检索.

And whenever you need to retrieve the value, retrieve the value from the VM, NOT the UI.

这篇关于WPF 自定义文本框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆