DependencyProperty не работает, если значение от привязки - PullRequest
0 голосов
/ 26 сентября 2019

Я создал UserControl с viewmodel.У него есть DependencyProperty, который работает, только если значение передается напрямую.Если значение передается через привязку, оно больше не работает.

Вот код представления:

Это закрытый элемент, не связанный ни с каким другим.Все перечисленные предметы принадлежат ему.Это сокращение кода, я не буду представлять целые, неизмеримые структуры.

Вид

public partial class SomeView : UserControl
{
    public SomeView()
    {
        InitializeComponent();
        SetBinding(ActiveProperty, new Binding(nameof(SomeViewModel.Active)) { Mode = BindingMode.OneWayToSource });
    }

    #region ActiveProperty
    public static readonly DependencyProperty ActiveProperty = DependencyProperty.Register(nameof(Active), typeof(bool), typeof(VNCBoxView));

    public bool Active
    {
        get { return (bool)GetValue(ActiveProperty); }
        set { SetValue(ActiveProperty, value); }
    }
}

VievModel

public class SomeViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private bool active;

    public bool Active
    {
        get { return active; }
        set
        {
            active = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Active)));
        }
    }
}

UserControl

<UserControl ...>
    <UserControl.DataContext>
        <viewModels:SomeViewModel />
    </UserControl.DataContext>
    <Grid>
        <TextBlock Text="{Binding Active}" />
    </Grid>
</UserControl>

========================================================

При работе с готовым компонентом, который является отдельным отдельным объектом, проблема возникает в зависимости от того, какиспользуется.Напоминаю, что элементы, используемые в рассматриваемом представлении, являются замкнутым целым, которое не связано с элементом, в котором оно используется.Проблема заключается в передаче значения.

Это рабочее использование:

<local:SomeView Active="True" />

В viewmodel сеттер вызывается дважды, один разсо значением false, а затем со значением true.

Если значение получено из привязки, оно не работает:

<local:SomeView Active="{Binding SomeParentProperty}" />

В viewmodel setter вызывается только один раз сзначение false.

Установщики в представлении никогда не вызываются, в обоих случаях.

Пожалуйста, помогите

Ответы [ 2 ]

1 голос
/ 26 сентября 2019

Нет свойства IsConnected в экземпляре SomeViewModel в текущем DataContext UserControl, поэтому привязка

<local:SomeView Active="{Binding IsConnected}" />

не будет работать.Он пытается сопоставить PropertyPath с текущим DataContext, если вы явно не укажете его Source, RelativeSource или ElementName.

Именно по этой причине UserControls должен никогда явноустановить свой собственный DataContext и, следовательно, никогда не иметь ничего похожего на собственную модель частного представления.

Элементы в XAML UserControl будут привязываться не к свойствам такого объекта модели частного представления, а непосредственно к свойствам объекта.UserControl, например,

<TextBlock Text="{Binding Active,
    RelativeSource={RelativeSource AncestorType=UserControl}}"/>
0 голосов
/ 26 сентября 2019

Когда вы явно устанавливаете DataContext в UserControl следующим образом:

<UserControl.DataContext>
    <viewModels:SomeViewModel />
</UserControl.DataContext>

... вы больше не можете привязываться к SomeView DataContext в режиме потребления, какthis:

<local:SomeView Active="{Binding IsConnected}" />

... потому что SomeViewModel не имеет никакого свойства IsConnected.

Вам следует избегать явной установки DataContext и позволить UserControl наследоватьDataContext от родительского элемента.Вы все еще можете привязать к свойству зависимостей самого UserControl, используя RelativeSource или ElementName:

<UserControl ...>
    <Grid>
        <TextBlock Text="{Binding Active, RelativeSource={RelativeSource AncestorType=UserControl}}" />
    </Grid>
</UserControl>

Кроме того, SomeViewModel кажется излишним в вашем примере, так как UserControl ужеимеет свойство Active.

...