设置DataContext后,依赖属性重置

本文关键字:属性 依赖 DataContext 设置 | 更新日期: 2023-09-27 18:11:31

我有一个UserControl (AgreementDetails)在WPF与以下DependencyProperty和function:

// UserControl AgreementDetails
    public int AgreementID
        {
            get { return Convert.ToInt32(GetValue(AgreementIDProperty)); }
            set { SetValue(AgreementIDProperty, value); }
        }
    public static readonly DependencyProperty AgreementIDProperty = DependencyProperty.Register("AgreementID", typeof(int), typeof(UC1001_AgreementDetails_View), new PropertyMetadata(null));
    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        int id = AgreementID;
        if (id > 0)
        {
            GetData();
            SetBindingContext();
            this.Visibility = System.Windows.Visibility.Visible;
        }
        else
        {
            this.Visibility = System.Windows.Visibility.Collapsed;
        }
    }
    private void GetData()
    {
        ConsultantServiceClient client = new ConsultantServiceClient();
        _contract = new UC1001_ActiveAgreementContract();
        _contract = client.GetAgreementDetailsByAgreementID(AgreementID);
    }
    private void SetBindingContext()
    {
        this.DataContext = _contract;
    }

我使用这个UserControl作为工具提示显示在另一个UserControl (Dashboard)中,我设置了agreemententid属性:

// Dashboard    
<Setter Property="DataGridCell.ToolTip">
      <Setter.Value>
             <my:UC1001_AgreementDetails_View Background="#FFF" Opacity="0.88" AgreementID="{Binding Months[9].AgreementID}"/>
      </Setter.Value>
</Setter>

在AgreementDetails中,我使用agreemententid从数据库中获取一些数据以显示在UserControl中。我第一次这么做,一切都很顺利。但是,当我将传入的WCF datcontract设置为AgreementDetails中的数据上下文时,AgreementID属性重置为0,因此第二次调用将不起作用,因为显然我没有与AgreementID = 0达成协议。我检查和协议id重置SetBindingContext();

我怎么能使它,所以协议id属性不会重置后,我设置了一个新的dataContext在协议细节?

如果需要,可以提供更多信息。

编辑:我现在有以下代码:

// Dependency properties
 public int AgreementID
 {
    get { return (int)GetValue(AgreementIDProperty); }
    set { SetValue(AgreementIDProperty, value); }
 }
 public UC1001_ActiveAgreementContract AgreementDetailsContract
 {
    get { return (UC1001_ActiveAgreementContract)GetValue(AgreementDetailsContractProperty); }
    set { SetValue(AgreementDetailsContractProperty, value); }
 }
    public static readonly DependencyProperty AgreementIDProperty = DependencyProperty.Register("AgreementID", typeof(int), typeof(UC1001_AgreementDetails_View), new PropertyMetadata(null));
    public static readonly DependencyProperty AgreementDetailsContractProperty = DependencyProperty.Register("AgreementDetailsContract", typeof(UC1001_ActiveAgreementContract), typeof(UC1001_AgreementDetails_View), new PropertyMetadata(null));
    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        int id = AgreementID;
        if (id > 0)
        {
            GetData();
            SetBindingContext();
            this.Visibility = System.Windows.Visibility.Visible;
        }
        else
        {
            this.Visibility = System.Windows.Visibility.Collapsed;
        }
    }
    private void GetData()
    {
        ConsultantServiceClient client = new ConsultantServiceClient();
        AgreementDetailsContract = client.GetAgreementDetailsByAgreementID(AgreementID);
    }
    private void SetBindingContext()
    {
       this.DataContext = AgreementDetailsContract;
    }

我仍然有问题,在DataContext设置后,agreemententid重置为0。

同样,当我使用下面的语句绑定时,我得到一个空标签:

<Label Content="{Binding RelativeSource={RelativeSource Self}, Path=AgreementDetailsContract.EndClientName}" />

解决:

我删除了SetDataBinding()方法,所以绑定不会重置我的DependencyProperty,对于标签的绑定,我使用了以下绑定(而不是RelativeSource Self):

 <Label Content="{Binding ElementName=AgreementDetails, Path=AgreementDetailsContract.EndClientName}" Grid.Column="1" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="11,0,0,0" Name="_labelEindklant" VerticalAlignment="Top" />

ElementName=AgreementDetails是我的UserControl的名称。奇怪的是,{RelativeSource Self}没有工作…

设置DataContext后,依赖属性重置

当你在Usercontrol中设置数据上下文时,你实际上也是在重置父控件(Dashboard)中的数据上下文。语境是一样的。因此,您的协议ID不再在上下文中,因此被重置。

编辑:实际上我没有把这个词写得很好。您没有影响Dashboard中的数据上下文,但是您影响了在该控件中声明的AgreementId绑定所使用的数据上下文。绑定是在Dashboard控件中声明的,但绑定实际上是在您正在重置的子控件的数据上下文中查找的。

在这里看到我类似的问题:在UserControl中设置DataContext会影响父

中的绑定

编辑:我的意思是:

// UserControl AgreementDetails
public int AgreementID
{
    get { return Convert.ToInt32(GetValue(AgreementIDProperty)); }
    set { SetValue(AgreementIDProperty, value); }
}
//The new property to bind to instead of DataContext
public UC1001_ActiveAgreementContract Agreement
{
    get { return (UC1001_ActiveAgreementContract)GetValue(AgreementProperty); }
    private set { SetValue(AgreementProperty, value); }
}
public static readonly DependencyProperty AgreementIDProperty = DependencyProperty.Register("AgreementID", typeof(int), typeof(UC1001_AgreementDetails_View), new PropertyMetadata(null));
//should really be readonly dependency property
public static readonly DependencyProperty AgreementProperty = DependencyProperty.Register("Agreement", typeof(UC1001_ActiveAgreementContract), typeof(UC1001_AgreementDetails_View), new PropertyMetadata(null));**
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    int id = AgreementID;
    if (id > 0)
    {
        GetData();
        SetBindingContext();
        this.Visibility = System.Windows.Visibility.Visible;
    }
    else
    {
        this.Visibility = System.Windows.Visibility.Collapsed;
    }
}
private void GetData()
{
    ConsultantServiceClient client = new ConsultantServiceClient();
    _contract = new UC1001_ActiveAgreementContract();
    _contract = client.GetAgreementDetailsByAgreementID(AgreementID);
}
private void SetBindingContext()
{
    this.Agreement = _contract;
}

然后在您的AgreementDetails。Xaml,你可能会有这样的东西:

<!-- Bound to property in DataContext -->
<TextBlock Text={Binding SomeContractProperty} />

哪个绑定需要更改为:

<!-- Bound to new property on UC1001_AgreementDetails_View (UserControl) -->
<TextBlock Text={Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UC1001_AgreementDetails_View}}, Path=Agreement.SomeContractProperty} />