我有一个正在使用的用户控件 DataTemplate, , 这 UserControl 包含一个 TextBox价值 属性(声明为 DependencyProperty)我的 UserControl. 。在数据模板中我绑定了这个 价值 财产与我的实际财产说 姓名 (也 DependencyProperty)。它工作正常,我分配了一个值 姓名 加载时的属性和我的 TextBox 显示它,我将值更改为 TextBox 它更新了我的 姓名 财产也。现在当我添加一个时出现问题 PropertyChangedEventHandler 在依赖属性中,我检查该值是否有效,如果有效则不执行任何操作,如果无效则分配旧值。如果值无效,当我为其分配旧值时,属性会更新,但它不会在我的中显示更新的值 TextBoxUserControl. 。谁能告诉我为什么?

XAML 我的 UserControl:

<UserControl x:Name="usercontrol">
   <StackPanel>
      <TextBlock ......./>
      <TextBox Binding={Binding ElementName=usercontrol, Path=Value, Mode=TwoWay}/>
   </StackPanel>
</UserControl>

在代码后面 价值 是一个 DependencyProperty

我在我的中使用这个 DataTemplate:

<HierarchicalDataTemplate DataType="{x:Type myLib:myClass}" ItemsSource="{Binding Children}">
    <Expander Header="{Binding}">
        <WrapPanel>
            <edproperty:TextPropertyEditor Caption="Name" Value="{Binding Name, Mode=TwoWay}"/>
            <edproperty:TextPropertyEditor .................../>
            <edproperty:TextPropertyEditor .................../>
            <edproperty:TextPropertyEditor ...................../>
        </WrapPanel>
    </Expander>
</HierarchicalDataTemplate>

我正在使用这个模板 TreeView. 。里面 TreeView 我在中输入值 TextBox 这更新了 价值 我的财产 UserControl, ,依次更新 姓名 的财产 myClass 我正在分配一个 PropertyChangedCallback 给我的 姓名 财产在 myClass, ,执行一些验证并重新分配 OldValue 如果验证失败。它依次更新 价值 财产也,但我仍然看到 TextBox 与我之前输入的值相同,而不是更新后的值。

public string Name
    {
        get
        {
            return (string)GetValue(NameProperty);
        }
        set
        {
            SetValue(NameProperty, value);
        }
    }

    // Using a DependencyProperty as the backing store for Name.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty NameProperty =
        DependencyProperty.Register("Name", typeof(string), typeof(myClass), new UIPropertyMetadata(null, OnNameChanged));

    protected static void OnNameChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        if(checkRequired && !IsValid(e.NewValue.ToString()))
        {
            checkRequired=false;
            (sender as myClass).Name = args.OldValue.ToString();
        }
    }

    private static bool IsValid(string name)
    {
         .............some logic here
    }
有帮助吗?

解决方案

在环视天,大量的搜索,我发现我的问题的解决方案

所有的验证完成,指定旧值和更新的关系是不属性后,我需要CAL UpdateTarget()方法,以更新我的文本框中的值。

这是什么解释了更好的解决方案

HTTP:/ /social.msdn.microsoft.com/forums/en-US/wpf/thread/c404360c-8e31-4a85-9762-0324ed8812ef/

其他提示

我知道这个问题是关于文本框但RichTextBox中你可以使用UpdateLayout请()。

rtb.AppendText("Text");
rtb.ScrollToEnd();
rtb.UpdateLayout();

看起来你正在打破结合时直接从代码中设置的属性值的后面。

您不应该修改属性的方式。使用值强制机制并在强制值回调验证输入。

阿努拉格,

我必须在这里做出很多假设,但我会尝试一下。

你可能有这样的事情......

// ...
public static string GetValue(Dependency obj)
{
   // ...
}

// ...
public static void SetValue(DependencyObject obj, string value)
{
    // ...
}

// Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty ValueProperty =
    DependencyProperty.RegisterAttached("Value", typeof(string), typeof(MyCustomControl), new UIPropertyMetadata(OnValuePropertyChanged));

public static void OnValuePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    string newValue = e.NewValue as string;

    // You validate your value here,
    // Then if fails, revert to old value.
    if(!SomeCondtion(newValue)) SetValue(obj,e.OldValue as string);

}

这绝对不是验证数据的最佳方法。还有其他更有效的方法可以为您提供更大的灵活性。

  1. 在您的 TexBox 上应用 ValidationRule。这是我的第一个建议,因为它可以让您在验证失败时控制显示错误。如果您需要简单的验证,请查看我的 文章.
  2. 侦听 TextBox.TextChanged 事件。这很麻烦,而且最多不能重复使用。
  3. 不要使用 DependecyPropertyChanged 回调方法。使用注册的字符串属性并在您的设置器中应用逻辑,例如

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(UserControlWithTextBox));
    
    
    private string _oldValue;
    public string Value
    {
        get { return GetValue(ValueProperty) as string; }
        set
        {
            // Check if the value passes your validation logic
            if(SomeCondtion(value))
            {
                // If yes, then set the value, and record down the old value.
                SetValue(ValueProperty, value);
                _oldValue = value;
            }
            else
            {
                // Else logic fails, set the value to old value.
                SetValue(ValueProperty, _oldValue);
            }
            // Implement INotifyPropertyChanged to update the TextBox.
            if(PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("Value"));
        }
    }
    

再次,正如您从我的回答中看到的那样,您仍然可以在问题中显示代码来帮助其他人回答您的问题,无论您的解决方案有多复杂(如果您想要一个好的答案,您需要努力询问一个好问题)。我的答案可能不适合你,但也许它可能会给你一些“谷歌搜索”的指导。希望能帮助到你。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top