【问题标题】:WPf Binding IssueWPf 绑定问题
【发布时间】:2010-12-08 01:39:48
【问题描述】:

我在 WPF 中创建了一个自定义控件,但无法正确绑定它。如果我在后面的代码中明确设置属性的值,一切正常。

这是我控制的TextBox 的 XAML:

<TextBox Name="txtText" Grid.Row="0" Grid.Column="0" IsReadOnly="True" Text="{Binding Text, Mode=OneWay}" />

而后面代码中的相关属性如下:

public static readonly DependencyProperty TextConverterProperty = DependencyProperty.Register("TextConverter", typeof(IValueConverter), typeof(Selector));
public static readonly DependencyProperty EntityIdProperty = DependencyProperty.Register("EntityId", typeof(long), typeof(Selector));

public string Text
{
    get
    {
        string result = this.EntityId.ToString();

        if (this.TextConverter != null)
        {
            result = this.TextConverter.Convert(result, null, null, null) as string;
        }

        return result;
    }
}

public long EntityId
{
    get
    {
        return (long)this.GetValue(EntityIdProperty);
    }
    set
    {
        this.SetValue(EntityIdProperty, value);

        this.OnPropertyChanged("Text");
        this.OnPropertyChanged("EntityId");
    }
}

public IValueConverter TextConverter
{
    get
    {
        return this.GetValue(TextConverterProperty) as IValueConverter;
    }
    set
    {
        this.SetValue(TextConverterProperty, value);
    }
}

现在我的页面中的 XAML 实现:

<controls:Selector x:Name="txtReferringCase" EntityId="{Binding ReferringDACaseId}" TextConverter="{StaticResource daCaseNumberConverter}" Grid.Column="5" Grid.Row="0" Grid.ColumnSpan="3" ButtonClicked="txtReferringCase_ButtonClicked" />

现在是奇怪的部分。我可以为页面设置 DataContext 并且没有任何反应,但是当我取消注释注释行时,文本会毫无问题地显示在我的用户控件中:

_caseScreen = new DACaseScreen(itemId);
this.DataContext = _caseScreen;
//this.txtReferringCase.EntityId = _caseScreen.ReferringDACaseId;

编辑:我忘记提及的另一件事...如果我遇到断点并检查控件的 EntityId 和 Text 属性,它们都会显示我期望的值。用户界面似乎没有更新。

【问题讨论】:

  • 更改DataContext后会发生什么?

标签: wpf binding user-controls


【解决方案1】:

DependencyProperties 的 Getter 和 Setter 只应调用 GetValueSetValue,因为 XAML 不使用它们只是为了方便。如果您想要额外的行为,请注册您的 DependencyProperty 并传入一个可以执行您想要的更改处理程序。

public static readonly DependencyProperty EntityIdProperty = DependencyProperty.Register("EntityId", typeof(long), typeof(Selector),new UIPropertyMetadata(EntityIdChanged));

public long EntityId
{
    get
    {
        return (long)this.GetValue(EntityIdProperty);
    }
    set
    {
        this.SetValue(EntityIdProperty, value);
    }
}

private static void EntityIdChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    var control = (Selector)sender;
    control.OnPropertyChanged("Text");
}

您无需为依赖属性调用PropertyChanged。我还需要更改UserControl 中的txtText 绑定,将源设置为控件本身而不是DataContext,但如果在代码中设置属性对你有用,那应该没问题。您可能想要重命名您的控件,因为有一个名为 Selector 的内置控件,但它并不那么重要。

【讨论】:

    【解决方案2】:

    在您拨打OnPropertyChanged 之前,您的用户界面不会更新。设置 DataContext 不会触发。

    除此之外你还做:

    public static readonly DependencyProperty TextConverterProperty = DependencyProperty.Register("TextConverter", typeof(IValueConverter), typeof(Selector));
    public static readonly DependencyProperty EntityIdProperty = DependencyProperty.Register("EntityId", typeof(long), typeof(Selector));
    

    但是你没有注册Text依赖,只有TextConverter和EntityId。意思是,您的 OnPropertyChanged 将不起作用(?)(或者您只是忘记在此处显示该行:))

    【讨论】:

    • 如果您不绑定 文本,则文本不具有依赖关系。您可以在“文本”上触发 OnPropertyChanged,即使它不是依赖属性
    猜你喜欢
    • 2010-12-09
    • 1970-01-01
    相关资源
    最近更新 更多