WPF:TextBox文本未更新

时间:2009-10-30 09:26:40

标签: wpf xaml textbox user-controls datatemplate

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

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

XAML

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 Value 属性,然后更新 Name 属性PropertyChangedCallback我正在为myClass中的名称属性分配OldValue,执行一些验证并在验证失败时重新分配TextBox。它反过来也会更新 Value 属性,但我仍然看到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 } 具有我之前输入的值,而不是更新的值。

{{1}}

4 个答案:

答案 0 :(得分:8)

经过几天的搜索和大量的搜索,我找到了解决问题的方法

完成所有验证并分配旧值并更新dependecy属性后,我需要调用UpdateTarget()方法,以更新TextBox中的值。

这就是更好地解释解决方案的原因

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

答案 1 :(得分:1)

我知道这个问题是关于TextBox的,但对于RichTextBox,你会使用UpdateLayout()。

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

答案 2 :(得分:0)

当您直接从后面的代码设置属性值时,看起来您正在破坏绑定。

您不应该以这种方式修改属性。使用value coercion mechanism并验证Coerce值回调中的输入。

答案 3 :(得分:0)

阿努拉格,

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

你可能有这样的东西......

// ...
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。这是我的第一个建议,因为它可以让您控制在验证失败时显示错误。如果您正在进行简单验证,请查看我的article
  2. 收听TextBox.TextChanged事件。这很麻烦,并且在大多数黑客攻击时都无法重复使用。
  3. 不要使用DependecyPropertyChanged回调方法。使用已注册的字符串属性并在您的setter中应用逻辑,例如

    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"));
        }
    }
    
  4. 再次,从我的回答中可以看出,无论您的解决方案有多复杂,您仍然可以在问题中显示代码以帮助其他人回答您的问题(如果您想要一个好的答案,则需要加入努力提出一个好问题)。我的回答可能不适合你,但可能会给你一些“谷歌搜索”的指示。希望它有所帮助。