简体   繁体   English

设置DataContext后重置依赖项属性

[英]Dependency Property reset after setting DataContext

I have a UserControl (AgreementDetails) in WPF with the following DependencyProperty and function: 我在WPF中有一个UserControl(AgreementDetails),具有以下DependencyProperty和功能:

// 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;
    }

I use this UserControl to show as a tooltip in another UserControl (Dashboard) where I set the AgreementID property: 我使用此UserControl在另一个设置了AgreementID属性的UserControl(仪表板)中显示为工具提示:

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

In AgreementDetails, I use the AgreementID to get some data from the database to show in the UserControl. 在AgreementDetails中,我使用AgreementID从数据库中获取一些数据以显示在UserControl中。 The first time I do this, everything goes smooth. 我第一次这样做,一切都会顺利进行。 But when I set the incoming WCF DataContract as the datacontext in AgreementDetails, the AgreementID property resets to 0, so the second call will not work because obviously I do not have an agreement with AgreementID = 0. I checked and the AgreementID resets in the SetBindingContext(); 但是,当我将传入的WCF DataContract设置为AgreementDetails中的datacontext时,AgreementID属性重置为0,因此第二个调用将不起作用,因为显然我没有AgreementID = 0的协议。我检查了一下,并在SetBindingContext中重置了AgreementID (); method after the DataContext is set. 设置DataContext之后的方法。

How can I make it so the AgreementID property will not reset after I set a new dataContext in AgreementDetails?? 我如何做到这一点,以便在我在AgreementDetails中设置新的dataContext后不会重置AgreementID属性?

More information can be provided if wanted. 如果需要,可以提供更多信息。

EDIT : I now have the following code: 编辑 :我现在有以下代码:

// 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;
    }

I still have the the problem that the AgreementID resets to 0 after the DataContext is set. 我仍然有一个问题,在设置了DataContext之后,AgreementID重置为0。

Also when I use the following statement to bind, I get an empty label: 同样,当我使用以下语句进行绑定时,也会得到一个空标签:

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

SOLVED: 解决了:

I removed the SetDataBinding() method so the Binding doesn't reset my DependencyProperty, and for the Binding of my labels I used the following Binding (instead of RelativeSource Self): 我删除了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 is the name of my UserControl. ElementName = AgreementDetails是我的UserControl的名称。 Strange enough with {RelativeSource Self} it didn't work... {RelativeSource Self}太奇怪了,它没有用...

When you set the datacontext in your Usercontrol, you are actually resetting the data context in the parent control too (Dashboard). 在用户控件中设置数据上下文时,实际上实际上也在父控件(仪表板)中重置了数据上下文。 It's the same context. 这是相同的上下文。 Because of this your Agreement ID is no longer in the context and so gets reset. 因此,您的协议ID不再存在于上下文中,因此将被重置。

Edit: Actually I didn't word that very well. 编辑:实际上我的话说得不太好。 You're not affecting the data context in Dashboard, but you ARE affecting the data context used by the AgreementId binding declared in that control. 您不会影响Dashboard中的数据上下文,但是会影响该控件中声明的AgreementId绑定所使用的数据上下文。 The binding is declared in the Dashboard control, but the binding is actually looking in the data context of the child control, which you are resetting. 绑定在Dashboard控件中声明,但是绑定实际上是在要重置的子控件的数据上下文中查找。

See my similar question here: Setting DataContext within UserControl is affecting bindings in parent 在这里看到我的类似问题: 在UserControl中设置DataContext正在影响父级中的绑定

EDIT: Here is what I mean: 编辑:这是我的意思:

// 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;
}

Then in your AgreementDetails.xaml, you probably have something like: 然后,在您的AgreementDetails.xaml中,您可能会有类似以下内容:

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

which binding needs to change to: 绑定需要更改为:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM