Сброс свойства зависимости после установки DataContext - PullRequest
1 голос
/ 17 октября 2011

У меня есть пользовательский элемент управления (AgreementDetails) в WPF со следующим свойством 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;
    }

Я использую этот UserControl для отображения в качестве всплывающей подсказки в другом UserControl (Dashboard), где я устанавливаю свойство AgreementID:

// 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 я использую AgreementID, чтобы получить некоторые данные из базы данных для отображения в UserControl. В первый раз, когда я делаю это, все идет гладко. Но когда я устанавливаю входящий WCF DataContract в качестве контекста данных в AgreementDetails, свойство AgreementID сбрасывается в 0, поэтому второй вызов не будет работать, потому что, очевидно, у меня нет соглашения с AgreementID = 0. Я проверил, и AgreementID сбрасывается в SetBindingContext (); метод после установки DataContext.

Как сделать так, чтобы свойство AgreementID не сбрасывалось после того, как я установил новый dataContext в AgreementDetails ??

При желании может быть предоставлена ​​дополнительная информация.

РЕДАКТИРОВАТЬ : Теперь у меня есть следующий код:

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

У меня по-прежнему проблема в том, что AgreementID сбрасывается в 0 после установки DataContext.

Также, когда я использую следующее выражение для привязки, я получаю пустую метку:

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

РЕШИТЬ:

Я удалил метод SetDataBinding (), чтобы Binding не сбрасывал мой DependencyProperty, а для Binding моих меток я использовал следующую Binding (вместо 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}, он не работал ...

1 Ответ

1 голос
/ 17 октября 2011

Когда вы устанавливаете текст данных в вашем Usercontrol, вы фактически сбрасываете контекст данных в родительском элементе управления (Dashboard). Это тот же контекст. Из-за этого ваш идентификатор соглашения больше не находится в контексте и поэтому сбрасывается.

Редактировать: На самом деле я не очень хорошо сказал это. Вы не влияете на контекст данных в Dashboard, но воздействуете на контекст данных, используемый связыванием AgreementId, объявленным в этом элементе управления. Привязка объявляется в элементе управления Dashboard, но привязка фактически просматривается в контексте данных дочернего элемента управления, который вы сбрасываете.

Смотрите мой похожий вопрос здесь: Настройка DataContext в UserControl влияет на привязки в родительском

РЕДАКТИРОВАТЬ: Вот что я имею в виду:

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