【问题标题】:How to bind TextBox.Text according to a string property that provides the name of the property I want to bind to?如何根据提供我要绑定的属性名称的字符串属性绑定 TextBox.Text?
【发布时间】:2019-07-25 12:32:28
【问题描述】:

WPF 相当初级 :)

上下文

我有一个包含几个整数的 DataContext 窗口。 我的窗口基本上只是用来显示每个 int 的“Key : Value”,Value 是一个可编辑的 TextBox。

当我编辑我的窗口以提供 ValueConverters 和 ValidationRules 时,我觉得我可以使用一些通用类,因为它们都有相同的规则/转换器。

问题

假设我有 int property_a, int property_b, int property_c;在我的数据上下文中。我不知道如何将泛型类中 TextBox 的内容绑定到这些属性:/

我想为我的泛型类提供一个像“property_a”这样的字符串属性,但是我找不到如何使用这个属性进行动态绑定。

代码示例

  • 我自定义的 TextBox 包装器:
<Grid>
        <TextBox x:Name="IntBox" Grid.Row="1" Grid.Column="1" Margin="0, 5, 10, 5"
                 Style="{StaticResource TextBoxInError}">
            <TextBox.Text>
                <Binding Path="{no idea what to put here }">
                    <Binding.ValidationRules>
                        <validation:IntRule />
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
    </Grid>
public partial class IntTextBox : UserControl
    {
        public string PropertyToBind { get; set; }

        public IntTextBox()
        {
            InitializeComponent();
        }
    }
  • 我在 Window 中使用 TextBox 包装器的地方:
<input:IntTextBox x:Name="InitiativeBox" Grid.Row="1" Grid.Column="1" Margin="0, 5, 10, PropertyToBind="Initiative"/>

感谢您的阅读:)

【问题讨论】:

  • 请不要在您的帖子中添加“已解决”。如果答案对你有用,只要接受就足够了。

标签: c# wpf xaml


【解决方案1】:

您将在后面的代码中创建绑定。 PropertyToBind 应该是一个依赖属性,因为它是 UI 元素的属性,您可能想要绑定它。我们还将它重命名为PropertyPath,因为这与在 WPF 框架中命名类似属性(如ListBox.SelectedValuePath)的方式是一致的。

这是 XAML。 Grid.Row 和 Grid.Column 索引从 0 开始,而不是 1。无论如何您都不需要它们,因为您没有在 Grid 中定义任何行或列(如果这是一个部分示例并且您只是省略了行/列定义,忽略那些评论)。

<Grid>
    <TextBox 
        x:Name="IntBox" 
        Margin="0, 5, 10, 5"
        Style="{StaticResource TextBoxInError}"
        />
</Grid>

后面的代码:

public partial class IntTextBox : UserControl
{
    public IntTextBox()
    {
        InitializeComponent();
    }

    public String PropertyPath
    {
        get { return (String)GetValue(PropertyPathProperty); }
        set { SetValue(PropertyPathProperty, value); }
    }

    public static readonly DependencyProperty PropertyPathProperty =
        DependencyProperty.Register(nameof(PropertyPath), typeof(String), 
            typeof(IntTextBox),
            new FrameworkPropertyMetadata(PropertyPath_PropertyChanged));

    protected static void PropertyPath_PropertyChanged(DependencyObject d, 
        DependencyPropertyChangedEventArgs e)
    {
        var ctl = d as IntTextBox;

        var binding = new Binding(ctl.PropertyPath)
        {
            ValidationRules = { new IntRule() },

            //  Optional. With this, the bound property will be updated and validation 
            //  will be applied on every keystroke. Fine for integers. For doubles 
            //  or phone numbers, it'll drive your users up the wall. 
            UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
        };

        ctl.IntBox.SetBinding(TextBox.TextProperty, binding);
    }
}

我不确定在这种特殊情况下您在这里所做的是否一定是一个好主意,但该技术是值得尊敬的,您就是这样做的。

【讨论】:

  • 好的,完全可以。 :) 你能解释一下转换是如何完成的吗?因为我看到您如何注册一个新的 DependencyProperty,但我看不到它将 TextBox(一个字符串)的内容转换为我的 DataContext(一个整数)中的变量的部分在哪里。它是嵌入在 DependencyProperty 中的任何类型的自动过程吗?
  • ctl.IntBox.SetBinding(TextBox.TextProperty, binding);。绑定根据需要进行类型转换。就像你刚刚做了&lt;TextBox Text="{Binding SomeIntProperty}" /&gt;一样。
  • 我猜,只要我们处理标准类型,它可以处理任何类型的转换(:
  • 是的。原始类型是自动处理的,WPF 框架类型具有类型转换器。你可以为你定义的类型写一个type converter,或者你可以写一个值转换器。
【解决方案2】:

您的问题的简短回答是: 您将公共属性的名称放在数据上下文中。

我不确定这是一个完全有用的答案。

您可能会发现这个示例发人深省:

https://social.technet.microsoft.com/wiki/contents/articles/29777.wpf-property-list-editing.aspx

也许你应该先看看一些超级简单的东西:

https://social.technet.microsoft.com/wiki/contents/articles/31915.wpf-mvvm-step-by-step-1.aspx

https://social.technet.microsoft.com/wiki/contents/articles/32164.wpf-mvvm-step-by-step-2.aspx

【讨论】:

  • 我稍后会检查链接,但我担心从简短的回答中我表达得不够好。整个想法是我想通过“PropertyToBind”而不是通过父级的DataContext传递要绑定的属性,这样我的类就可以通过更改“PropertyToBind”来用于所有property_a、property_b和property_c
猜你喜欢
  • 2012-07-20
  • 2011-10-03
  • 2017-11-29
  • 2011-09-18
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多