【问题标题】:Use a binding to set the text property of a textbox in a usercontrol - WPF使用绑定在用户控件中设置文本框的文本属性 - WPF
【发布时间】:2013-12-10 13:06:44
【问题描述】:

我有一个包含文本框的用户控件,并在用户控件中创建了一个获取/设置来获取/设置文本框的文本属性。

public class OpenFileControl : UserControl
{
    StackPanel sp;
    public TextBox tb;

    public string Text { get { return tb.Text; } set { tb.Text = value; } }

然后我想稍后根据绑定设置此值 -

<gX3UserControls:OpenFileControl Text="{Binding Value}"  />

但我得到以下异常 不能在“OpenFileControl”类型的“文本”属性上设置“绑定”。 “绑定”只能在 DependencyObject 的 DependencyProperty 上设置。

经过一番调查,似乎 Text 需要是一个依赖属性,但如果我这样做,我无法弄清楚如何将值传递给文本框。

我该如何解决这个问题。

【问题讨论】:

    标签: c# wpf binding


    【解决方案1】:

    考虑使用类似的东西。

    控制 XAML:

    <UserControl x:Class="WpfTestBench.OpenFileControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <StackPanel>
            <TextBox Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, 
                Path=Filename, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>
    </UserControl>
    

    控制代码隐藏:

    using System.Windows;
    
    namespace WpfTestBench
    {
        public partial class OpenFileControl
        {
            public static readonly DependencyProperty FilenameProperty =
                DependencyProperty.Register("Filename", typeof (string), typeof (OpenFileControl));
    
            public OpenFileControl()
            {
                InitializeComponent();
            }
    
            public string Filename
            {
                get { return (string)GetValue(FilenameProperty); }
                set { SetValue(FilenameProperty, value); }
            }
        }
    }
    

    主要 XAML:

    <Window x:Class="WpfTestBench.OpenFileWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:wpfTestBench="clr-namespace:WpfTestBench"
            Title="OpenFileWindow" Width="300" SizeToContent="Height">
        <StackPanel>
           <wpfTestBench:OpenFileControl x:Name="In" Filename="{Binding SelectedFilename, UpdateSourceTrigger=PropertyChanged}" />
           <wpfTestBench:OpenFileControl x:Name="Out" Filename="{Binding ElementName=In, Path=Filename}" />
        </StackPanel>
    </Window>
    

    主要代码隐藏:

    namespace WpfTestBench
    {
        public partial class OpenFileWindow
        {
            public OpenFileWindow()
            {
                InitializeComponent();
    
                DataContext = this;
            }
    
            public string SelectedFilename { get; set; }
        }
    }
    

    执行结果(在第一个控件中输入内容后):

    【讨论】:

    • +1 如果相对源绑定不是您的朋友,您也可以进行元素名绑定: :)
    【解决方案2】:

    如果将依赖属性定义为静态属性和实际属性,则可以在属性主体中编写任何代码。

    public const string TextPropertyName = "Text";
    public string Text
        {
            get
            {
                return (string)GetValue(TextProperty);
            }
            set
            {
                SetValue(TextProperty, value);
            }
        }
    
     public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
            TextPropertyName,
            typeof(string),
            typeof(MyControl),
            new UIPropertyMetadata(false));
    

    在 getter 和 setter 中,您可以执行类似 textBox1.Text = value; 的操作。但是使用与属性的绑定可能会更好地为您服务。 MVVM 框架经常使这类事情变得轻松。您可能会发现定义 ViewModel(例如具有适当的 FielPath 变量的类)并将新 UserControl 的 DataContext 设置为 ViewModel 类的实例会更成功,使用 Bindings 为您完成繁重的工作。

    【讨论】:

    • 请注意,使用此语句 new UIPropertyMetadata(false) 将导致 ArgumentException,因为字符串无法使用 bool 值初始化。
    • 非常正确,我的错误,null 应该更好地作为 Register 命令的最终参数
    猜你喜欢
    • 2012-12-31
    • 2014-01-26
    • 2016-02-12
    • 2011-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    相关资源
    最近更新 更多