Помогите с очень простой привязкой данных WPF - PullRequest
2 голосов
/ 16 мая 2009

Я новичок в WPF и пробую простой пример привязки данных, но он не работает. В моем окне есть TextBlock, который я привязал к свойству объекта окна. Я объявил собственность в коде.

При запуске я вижу правильное значение в TextBlock. Также есть кнопка, которая при нажатии обновляет свойство, за исключением того, что я не вижу, как это влияет на TextBlock.

Я правильно реализовал INotifyPropertyChanged, насколько я могу определить. Я также вижу при отладке, что что-то подписалось на событие PropertyChanged, за исключением того, что оно, похоже, ничего не делает.

У меня есть 2 вопроса:

1) Почему это не работает, как ожидалось?

2) Есть ли простой способ отладки во время выполнения, что вызывает это, не прибегая к сторонним инструментам? Из моих беглых знаний мне кажется, что поддержки отладки в WPF крайне не хватает.

XAML (не включая «стандартный» элемент окна XAML):

<TextBlock Height="28" Name="label1" VerticalAlignment="Top"
       Text="{Binding Path=TheName}"
       Grid.Row="0"
       ></TextBlock>
<Button Height="23" Name="button1" VerticalAlignment="Stretch" Grid.Row="1"
Click="button1_Click">
    Button
</Button>

Код в классе окна:

    public partial class Window1 : Window
    {
        protected MyDataSource TheSource { get; set; }

        public Window1()
        {
            InitializeComponent();
            TheSource = new MyDataSource();
            TheSource.TheName = "Original";  // This works
            this.label1.DataContext = this.TheSource;
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            TheSource.TheName = "Changed";  // This doesn't work
        }
    }
    public class MyDataSource : INotifyPropertyChanged
    {
        string thename;
        public string TheName 
        {
            get { return thename; }
            set { thename = value; OnPropertyChanged(thename); }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }
    }
}

Ответы [ 3 ]

7 голосов
/ 17 мая 2009

Проблема в том, что вы установили свойство "TheName". Вызов метода OnPropertyChanged передает значение "thename", а не "name" of "thename". (Извините, если это не имеет смысла - имена переменных, использованные в примере, сговорились против нас!)

Правильный код будет:

string thename;
public string TheName 
{
  get { return thename; }
  set { thename = value; OnPropertyChanged("TheName"); }
}

Здесь - пример из MSDN .

Надеюсь, это поможет!

3 голосов
/ 19 мая 2009

Из блога Bea Stollnitz , вот несколько способов отладки привязки WPF.

  • Проверьте окно вывода, так как WPF регистрирует там много ошибок

  • Вы можете добавить источник трассировки в ваш app.config. Подробности в блог Майка Хиллберга

  • Добавить уровень трассировки в привязку (это мой любимый). Добавьте пространство имен xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
    и в привязке добавьте уровень трассировки
    <TextBlock Text="{Binding Path=TheName, diagnostics:PresentationTraceSources.TraceLevel=High}" />

  • Добавьте преобразователь в привязку, а затем установите в нем точку останова.

0 голосов
/ 19 мая 2009

Хорошо, спасибо, я не обратил достаточного внимания при чтении аргументов PropertyChangedEventArgs. Кажется, что хрупкий дизайн полагается на строку для имени свойства, но, очевидно, другие люди тоже так думают (по ссылке внизу комментариев пользователя на той странице MSDN, на которую вы ссылались).

Однако мой второй вопрос до сих пор остается без ответа: как я могу отладить это и выяснить, что я сделал не так?

Например, не записывает ли WPF свои действия в какой-либо форме? Следует заметить, что у меня нет свойства «Изменено» для этого объекта, почему он не вызывает исключение или, по крайней мере, не записывает что-то в консоль отладки?

...