简体   繁体   中英

Dependency Property reset after setting DataContext

I have a UserControl (AgreementDetails) in WPF with the following DependencyProperty and 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;
    }

I use this UserControl to show as a tooltip in another UserControl (Dashboard) where I set the AgreementID property:

// 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. 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(); method after the DataContext is set.

How can I make it so the AgreementID property will not reset after I set a new dataContext in AgreementDetails??

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.

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):

 <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. Strange enough with {RelativeSource Self} it didn't work...

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.

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. 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.

See my similar question here: Setting DataContext within UserControl is affecting bindings in parent

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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