You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF:如何将UserControl的TextBase绑定至Window代码后台

问题描述

尝试将自定义UserControl的TextBase字符串属性绑定到Window代码后台的Reame属性,目前可通过TextBox_Reame.TextBase直接取值,但希望通过数据绑定实现双向同步,且不想为该Window使用ViewModel。


UserControl XAML代码

<UserControl
     x:Class="PasswordManager.Helpers.Resource_UserDefined.TextBox_Hint"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:local="clr-name"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     Name="TextBoxUserWindow"
     d:DesignHeight="60" d:DesignWidth="800"
     mc:Ignorable="d">

<Grid Margin="20,0,20,0">

    <TextBox
        Name="txtSearchBox"
        Padding="0,0,0,3"
        VerticalContentAlignment="Center"
        Background="{Binding Background, RelativeSource={RelativeSource AncestorType=UserControl}}"
        BorderBrush="{Binding BorderColorBrush, RelativeSource={RelativeSource AncestorType=UserControl}}"
        BorderThickness="{Binding BorderThickness, RelativeSource={RelativeSource AncestorType=UserControl}}"
        FontFamily="{Binding FontFamily, RelativeSource={RelativeSource AncestorType=UserControl}}"
        FontSize="{Binding FontSize, RelativeSource={RelativeSource AncestorType=UserControl}}"
        Text="{Binding TextBase, RelativeSource={RelativeSource AncestorType=UserControl}}"
        TextChanged="txtSearchBox_TextChanged" />

    <TextBlock
        x:Name="txt_HintBox"
        Margin="3,0,0,0"
        VerticalAlignment="Center"
        Background="Transparent"
        FontFamily="{Binding FontFamily, RelativeSource={RelativeSource AncestorType=UserControl}}"
        FontSize="{Binding FontSize, RelativeSource={RelativeSource AncestorType=UserControl}}"
        FontStyle="{Binding FontStyle, RelativeSource={RelativeSource AncestorType=UserControl}}"
        Foreground="{Binding ForegroundColorOverlay, RelativeSource={RelativeSource AncestorType=UserControl}}"
        IsHitTestVisible="False"
        Text="{Binding Hint, ElementName=TextBoxUserWindow}" />
    </Grid>
</UserControl>

UserControl 后台代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace PasswordManager.Helpers.Resource_UserDefined
{
    public partial class TextBox_Hint : UserControl, INotifyPropertyChanged
    {
        public TextBox_Hint()
        {
            InitializeComponent();
        }

        public string TextBase
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); OnPropertyChanged(); }
        }

        // Using a DependencyProperty as the backing store for TextBase. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("TextBase", typeof(string), typeof(TextBox_Hint));

        public string Hint
        {
            get { return (string)GetValue(HintProperty); }
            set { SetValue(HintProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Hint. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HintProperty = DependencyProperty.Register("Hint", typeof(string), typeof(TextBox_Hint), new PropertyMetadata(""));

        public Brush Background
        {
            get { return (Brush)GetValue(BackgroundProperty); }
            set { SetValue(BackgroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for background. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register("Background", typeof(Brush), typeof(TextBox_Hint), new PropertyMetadata(Brushes.White));

        public Brush BorderColorBrush
        {
            get { return (Brush)GetValue(BorderColorBrushProperty); }
            set { SetValue(BorderColorBrushProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BorderColorBrush. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BorderColorBrushProperty = DependencyProperty.Register("BorderColorBrush", typeof(Brush), typeof(TextBox_Hint), new PropertyMetadata(Brushes.Black));

        public Thickness BorderThickness
        {
            get { return (Thickness)GetValue(BorderThicknessProperty); }
            set { SetValue(BorderThicknessProperty, value); }
        }

        // Using a DependencyProperty as the backing store for BorderThickness. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BorderThicknessProperty = DependencyProperty.Register("BorderThickness", typeof(Thickness), typeof(TextBox_Hint), new PropertyMetadata(new Thickness(1,1,1,1)));

        public Brush ForegroundColorOverlay
        {
            get { return (Brush)GetValue(ForegroundColorOverlayProperty); }
            set { SetValue(ForegroundColorOverlayProperty, value); }
        }

        // Usando un DependencyProperty come memorizzazione per ForegroundColorOverlay
        public static readonly DependencyProperty ForegroundColorOverlayProperty = DependencyProperty.Register("ForegroundColorOverlay", typeof(Brush), typeof(TextBox_Hint), new PropertyMetadata(Brushes.Gray));

        public FontFamily FontFamily
        {
            get { return (FontFamily)GetValue(FontFamilyProperty); }
            set { SetValue(FontFamilyProperty, value); }
        }

        // Using a DependencyProperty as the backing store for FontFamily. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FontFamilyProperty = DependencyProperty.Register("FontFamily", typeof(FontFamily), typeof(TextBox_Hint), new PropertyMetadata(new FontFamily("Arial")));

        public FontStyle FontStyle
        {
            get { return (FontStyle)GetValue(FontStyleProperty); }
            set { SetValue(FontStyleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for FontStyle. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FontStyleProperty = DependencyProperty.Register("FontStyle", typeof(FontStyle), typeof(TextBox_Hint), new PropertyMetadata(FontStyles.Normal));

        public Double FontSize
        {
            get { return (Double)GetValue(FontSizeProperty); }
            set { SetValue(FontSizeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for FontSize. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register("FontSize", typeof(Double), typeof(TextBox_Hint), new PropertyMetadata(20.0));

        private void txtSearchBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (string.IsNullOrEmpty(txtSearchBox.Text))
                txt_HintBox.Visibility = Visibility.Visible;
            else
                txt_HintBox.Visibility = Visibility.Hidden;
        }

        public event PropertyChangedEventHandler? PropertyChanged;

        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Window中使用UserControl的原代码

<userControls:TextBox_Hint
x:Name="TextBox_Reame"
Height="40"
BorderColorBrush="Black"
BorderThickness="0,0,0,1"
FontFamily="{DynamicResource Abel}"
FontSize="20"
FontStyle="Italic"
ForegroundColorOverlay="Gray"
Hint="Inserisci Il Reame"
TextBase="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type userControls:TextBox_Hint}}, Path=TextBase}">
<userControls:TextBox_Hint.Background>
    <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
        <GradientStop Offset="0.0" Color="White" />
        <GradientStop Offset="0.5" Color="#FFE1FFE6" />
        <GradientStop Offset="1.0" Color="White" />
    </LinearGradientBrush>
</userControls:TextBox_Hint.Background>
  </userControls:TextBox_Hint>

Window后台属性代码

private string _Reame;

public string Reame
{
    get { return _Reame; }
    set { _Reame = value; OnPropertyChanged(); }
}

解决方案

步骤1:修正UserControl的TextBase依赖项属性定义

当前TextBase的CLR属性多余调用了OnPropertyChanged,依赖项属性本身自带变更通知机制;同时依赖项属性的注册名称需与CLR属性名匹配,避免混淆:

public string TextBase
{
    get { return (string)GetValue(TextBaseProperty); }
    set { SetValue(TextBaseProperty, value); }
}

// 修正依赖项属性名称,与CLR属性名一致
public static readonly DependencyProperty TextBaseProperty = 
    DependencyProperty.Register(nameof(TextBase), typeof(string), typeof(TextBox_Hint), new PropertyMetadata(string.Empty));

步骤2:将Window的DataContext设为自身

在Window的构造函数中添加代码,让绑定自动查找窗口自身的属性:

public YourWindowClassName()
{
    InitializeComponent();
    DataContext = this;
}

步骤3:修改UserControl的绑定表达式

把TextBase的绑定指向窗口的Reame属性,并设置双向绑定+实时更新触发:

<userControls:TextBox_Hint
x:Name="TextBox_Reame"
Height="40"
BorderColorBrush="Black"
BorderThickness="0,0,0,1"
FontFamily="{DynamicResource Abel}"
FontSize="20"
FontStyle="Italic"
ForegroundColorOverlay="Gray"
Hint="Inserisci Il Reame"
TextBase="{Binding Reame, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<userControls:TextBox_Hint.Background>
    <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
        <GradientStop Offset="0.0" Color="White" />
        <GradientStop Offset="0.5" Color="#FFE1FFE6" />
        <GradientStop Offset="1.0" Color="White" />
    </LinearGradientBrush>
</userControls:TextBox_Hint.Background>
</userControls:TextBox_Hint>

关键说明

  • Mode=TwoWay:确保TextBase与Reame双向同步,一方变更另一方自动更新
  • UpdateSourceTrigger=PropertyChanged:文本内容变化时立即更新绑定源(默认是失去焦点时更新),实现实时同步

内容的提问来源于stack exchange,提问作者user27828246

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:47:02