WPF DependencyProperties - PullRequest
       24

WPF DependencyProperties

6 голосов
/ 25 ноября 2008

Я только что понял, что заставляю свойства привязки / зависимости и не совсем понимаю концепцию.

Вот свойство зависимости:

public string Problem
{
    get { return (string)GetValue(ProblemProperty); }
    set { SetValue(ProblemProperty, value); }
}

public static readonly DependencyProperty ProblemProperty =
    DependencyProperty.Register(
    "Problem",
    typeof(string),
    typeof(TextBox));

XAML выглядит так:

<TextBlock Text="{Binding Path=Problem}"/>

Я вручную устанавливаю для свойства Problem значение в конструкторе объекта, но оно не обновляет TextBlock соответственно. , , есть идеи? Я пробовал Mode="OneWay" и Mode="TwoWay" на привязке, но она все еще не работает.

Я думал, что это должно работать автоматически? Или я в корне ошибаюсь?

Спасибо

Ответы [ 6 ]

11 голосов
/ 25 ноября 2008

Ваша проблема определенно связана с вашим DataContext. Расширение {Binding} должно знать, где находится свойство, к которому вы привязываете. Расположение по умолчанию, на которое он смотрит, - это элементы DataContext, которые по умолчанию всегда устанавливаются на DataContext его родительского элемента. Если вы проведете DataContext вверх по логическому дереву к родительскому окну, DataContext будет нулевым (поскольку DataContext вашего окна будет нулевым). Поэтому ваш {Binding} в вашем текстовом блоке говорит: «Привязать свойство« Мой текст »к свойству Проблема моего DataContext ..., которое является нулевым».

Есть несколько способов решить эту проблему. Можно было бы сделать так, как упоминал Джоби, и установить свойство Element вашей привязки так, чтобы оно указывало на окно, где свойство DependencyProperty определено следующим образом:

<TextBlock Text="{Binding Path=Problem,ElementName=_window}" />

Другой вариант - установить DataContext вашего окна так, чтобы он указывал на себя. Таким образом, все элементы, содержащиеся в его содержимом, будут иметь DataContext окна.

<Window ....
        DataContext="{Binding RelativeSource={RelativeSource Self}}">

Теперь в любое время вам нужно привязать к свойствам, определенным в окне (например, к свойству зависимости Проблемы), тогда вы можете просто сделать это:

<TextBlock Text="{Binding Problem}" />
2 голосов
/ 22 марта 2012

попробуйте typeof(object) вместо typeof(string).

2 голосов
/ 25 ноября 2008

Вы можете использовать привязку ElementName здесь, элементом будет само окно.

<Window x:Class="WpfToolTip.Window1"
x:Name="_window"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <StackPanel>
        <Button Click="OnClick" Content="OK" />
        <Button Click="OnCancel" Content="Cancel" />
        <TextBlock Text="{Binding Path=Problem,ElementName=_window}" />
</StackPanel>

0 голосов
/ 26 августа 2010

Есть два способа понять причину проблемы, которую вы описали.

Сначала - вы должны попытаться установить обработчик измененного свойства (в объявлении свойства зависимостей) и установить точку останова. Вы увидите, меняется ли ваша собственность или нет.

Во-вторых, вы должны проверить тип владельца свойства зависимостей.

Не могли бы вы показать полный xaml и codebehind?

0 голосов
/ 24 февраля 2009

В вашем коде вы регистрируете свойство зависимости для класса TextBox (последняя строка цитаты).

public static readonly DependencyProperty ProblemProperty =
DependencyProperty.Register (
"Проблема",
TypeOf (строка),
TypeOf (TextBox));

Таким образом, вы можете установить значение для ProblemProperty только для текстовых полей, но я не могу найти текстовое поле ни в одном из фрагментов кода. Вам следует зарегистрировать свойство зависимости для типа, которому будет присвоено значение, из вашего примера правильный выбор для меня не очевиден. Вы можете, как это делает Мика, определить его как DP окна, а затем установить свойство в созданном вами окне. Или вы можете определить его для любого именованного объекта зависимости внутри окна, то есть для некоторого объекта с Name = m_ContentElement, а затем установить привязку на
{Binding ElementName=m_ContentElement, Path=Problem}
или короче:
{Binding Problem, ElementName=m_ContentElement}

0 голосов
/ 25 ноября 2008

Это окно, в котором он установлен.

public partial class Window1 : Window
{
    public string Problem
    {
        get { return (string)GetValue(ProblemProperty); }
        set { SetValue(ProblemProperty, value); }
    }

    public static readonly DependencyProperty ProblemProperty =
                    DependencyProperty.Register(
                    "Problem",
                    typeof(string),
                    typeof(Window1));


    public Window1()
    {
        InitializeComponent();

        Problem = "ifowiof";
    }

    public void OnClick(object sender, EventArgs e)
    {
        Problem = "behl";
    }

    public void OnCancel(object sender, EventArgs e)
    {
       Problem = "eioeopje";
    }
}

XAML:

<Window x:Class="WpfToolTip.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        <StackPanel>
            <Button Click="OnClick" Content="OK" />
            <Button Click="OnCancel" Content="Cancel" />
            <TextBlock Text="{Binding Path=Problem}" />
    </StackPanel>
</Window>

Это работает, если я устанавливаю RelativeSource, как вы сказали, когда он загружается, но если я изменяю свойство Problem в коде вручную (т.е. нажатием кнопки), он никогда не обновляет TextBlock новым значением .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...