title | description | ms.date | ms.topic | helpviewer_keywords | author | ms.author | manager | ms.technology | ms.workload | monikerRange | ||
---|---|---|---|---|---|---|---|---|---|---|---|---|
XAML data binding diagnostics |
Use new tools in Visual Studio to detect and resolve data binding errors in XAML projects. |
03/28/2022 |
conceptual |
|
maddymontaquila |
maleger |
jmartens |
vs-xaml-tools |
multiple |
>=vs-2019 |
XAML data binding diagnostics
[!INCLUDE Visual Studio]
Developers who work on XAML projects often have to detect and resolve XAML data binding failures in their applications. Now there are tools within Visual Studio 2019 version 16.8 or later and Visual Studio 2022 to help find these annoying data binding failures while you debug your application. Examples of common binding failures are as follows:
- Binding to a property name that doesn’t exist:
{Binding Wrong.Name}
- Binding to a value of the wrong type, like binding to a Boolean when an enumeration is required:
Visibility="{Binding IsVisible}"
Because these bindings are computed at runtime by using reflection, the XAML editor isn’t always able to catch them, and your build will still succeed. The failure happens only at runtime.
XAML data binding is explained in these articles:
- For WPF: Data binding overview — WPF .NET
- For UWP: Data binding overview — UWP applications
- For Xamarin.Forms: Xamarin.Forms Data Binding — Xamarin
Binding failures have always been written to the debug output window in Visual Studio. But it’s easy to miss the binding failures within debug output since it contains other debugging information that scrolls binding failures out of view. Here’s an example of a WPF binding failure within the debug output window:
:::image type=»content» source=»media/xaml-binding-failures-output-window-inline.png» alt-text=»Screenshot of the output window containing a binding failure.» lightbox=»media/xaml-binding-failures-output-window-expanded.png»:::
The binding failure might be hundreds of lines off the top of the window, and the text doesn’t tell you exactly which binding had the failure, so you need to think about it and search.
Now, with the XAML Binding Failures tool window, you can clearly see which bindings have failed, along with relevant data for each failure, such as the file location within XAML. Plus, there are many useful features for investigating the failures by searching, sorting, and even opening the XAML editor with focus set on the failed binding.
:::image type=»content» source=»media/xaml-binding-failures-window-inline.png» alt-text=»Screenshot of the XAML Binding Failures tool window.» lightbox=»media/xaml-binding-failures-window-expanded.png»:::
Double-clicking those rows opens the source XAML for the binding, as shown in the following image:
:::image type=»content» source=»media/xaml-binding-failures-example-inline.png» alt-text=»Screenshot of example bindings in the XAML editor.» lightbox=»media/xaml-binding-failures-example-expanded.png»:::
XAML Binding Failures tool window
The XAML Binding Failures tool window is available during debugging. To open it, go to Debug > Windows > XAML Binding Failures.
:::image type=»content» source=»media/xaml-binding-failures-menu.png» alt-text=»Screenshot of the XAML Binding Failures option in the Debug menu.»:::
Or, select the Binding failures button in the application toolbar. The number next to the icon shows how many binding failures are shown in the tool window.
:::image type=»content» source=»media/xaml-binding-failures-in-app.png» alt-text=»Screenshot of the in-app toolbar showing the binding failures button.»:::
When there are no binding failures in the tool window, the icon shows as gray without a number next to it. This is helpful while running your application. If you see the icon turn red with a number, click it to quickly jump to the tool window to see what binding failures occurred. There’s no need to keep an eye on the Visual Studio tool windows. When a binding fails the icon will tell you right away.
:::image type=»content» source=»media/xaml-binding-failures-in-app-2.png» alt-text=»Screenshot of the in-app toolbar showing the binding failures button with no failures.»:::
A similar icon also appears in the Live Visual Tree tool window.
:::image type=»content» source=»media/xaml-binding-failures-live-visual-tree.png» alt-text=»Screenshot of the binding failures button within the Live Visual Tree tool window.»:::
The following is a description of all components of the XAML Binding Failures tool window.
:::image type=»content» source=»media/xaml-binding-failures-callouts-inline.png» alt-text=»Screenshot of XAML Binding Failures tool window.» lightbox=»media/xaml-binding-failures-callouts-expanded.png»:::
- The toolbar at the top contains buttons as follows:
- Clear the list of failures: This is useful if you’re about to show a new page in your app and want to see if any binding failures show up. When you start a new debugging session, the list is automatically cleared.
- Delete selected rows: If a failure has been fixed or isn’t relevant, you can delete it from the list. Deleted rows will show up again if the binding fails again.
- Clear all filters: If there are any filters on the list, such as searching for text, then this button will clear them and show the full list.
- Combine Duplicates: Often the same binding will fail many times in a row when it is within an item template. When the Combine Duplicates button is selected (with an outline around it) then all duplicate failures are shown as a single row. The Count column will show how many times the failure occurred.
- The Search Binding Failures box in the top corner lets you filter the failures to only those that contain specific text.
- The table columns, in order, show:
- An icon that shows if the row is for an error or warning.
- An icon that shows angle brackets
<>
if navigating to the failed{Binding}
in XAML is supported. See the Supported Platforms section. - Data Context: This is the type name for the binding’s source object
- See Binding.Source
- Binding Path: This is the property path for the binding
- See Binding.Path
- Target: This is the type and property name where the binding’s value will be set.
- See BindingExpressionBase.Target and BindingExpressionBase.TargetProperty
- Target Type: This is the expected type of the binding’s target property.
- See BindingExpressionBase.TargetProperty
- Description: This column contains more information about what exactly failed for the binding.
- File, Line, and Project: If known, this is the location in XAML where the binding is defined.
- Right-clicking a row or multiple selected rows will show a context menu, with standard options for showing/hiding columns or grouping them. Other options are as follows:
- Copy all the text from a row or just a single column to the clipboard.
- Copy Original Error will copy the text that appeared in the debug output window.
- View Source will go to the binding source in XAML for one selected row.
- Reset Columns will undo all changes to column visibility and sorting, getting you back quickly to what was originally shown.
To sort the list, click any column header. To sort again by an extra column, hold down the Shift key and click another column header. To select which columns are displayed and which are hidden, choose Show Columns from the shortcut menu. To change the order in which columns are displayed, drag any column header to the left or right.
After you double-click a row or press Enter to navigation to the source, you can press F8 or Shift+F8 to move down or up through the list of binding failures. This is like other panes in Visual Studio that show a list.
Supported platforms
Most XAML platforms are supported if binding failures are written to debug output. Some platforms supply extra source information to the debugger that allows navigating to the source.
Platform | Supported | Navigate to source supported |
---|---|---|
WPF .NET Framework | Yes | No |
WPF .NET 5.0 RC2+ | Yes | Yes |
UWP | Yes | No |
WinUI3 desktop | Yes | No |
MAUI (Multi-platform App UI) | Yes | No |
Xamarin 4.5.0.266-pre3+ | Yes | Yes |
Xamarin before 4.5.0.266-pre3 | No | No |
The XAML Hot Reload option must be enabled in Visual Studio for navigating to source to work. This option is in the Tools > Options > Debugging dialog:
:::image type=»content» source=»media/xaml-binding-failures-hot-reload-option.png» alt-text=»Screenshot of the XAML Hot Reload options dialog.»:::
Navigating to source only works for bindings defined in XAML source files, not if they’re created through code. You can clearly see which rows support navigating to the source. If there’s no angle bracket icon in the second column, then navigating to source isn’t supported, such as with the highlighted row in the following screenshot:
:::image type=»content» source=»media/xaml-binding-failures-no-go-to-code.png» alt-text=»Screenshot showing a XAML binding failure without a source location.»:::
For WPF in .NET Framework, data binding failures must be shown in the debug output for the XAML Binding Failures pane to detect and show them. The option for this is in the Tools > Options > Debugging > Output Window > WPF Trace Settings dialog. If the setting is either Off or Critical, then data binding errors aren’t written to debug output and can’t be detected. With WPF in .NET 5, .NET 6, and later the data binding output setting doesn’t affect the failure list.
:::image type=»content» source=»media/xaml-binding-failures-wpf-output-options.png» alt-text=»Screenshot of WPF output options.»:::
See also
- XAML Hot Reload
kotelok 1006 / 625 / 212 Регистрация: 08.08.2014 Сообщений: 1,943 |
||||||||
1 |
||||||||
10.01.2020, 21:54. Показов 5082. Ответов 6 Метки нет (Все метки)
Работает, все элементы отрисовывает в ожидаемых позициях, но при этом каждый раз сообщает: System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression: (no path); DataItem=null; target element is ‘EllipseGeometry’ (HashCode=29135240); target property is ‘Center’ (type ‘Point’) Подскажите, в чём суть и как это исправить? Наугад попробовал разные комбинации ‘ElementName’ и ‘RelativeSource’, не помогло.
0 |
управление сложностью 1687 / 1300 / 259 Регистрация: 22.03.2015 Сообщений: 7,545 Записей в блоге: 5 |
|
10.01.2020, 22:52 |
2 |
Биндинг возможен к открытым свойствам контекста данных
0 |
Элд Хасп Модератор 13812 / 10018 / 2668 Регистрация: 21.04.2018 Сообщений: 29,816 Записей в блоге: 2 |
||||||||||||
11.01.2020, 11:41 |
3 |
|||||||||||
Решение
Подскажите, в чём суть и как это исправить? kotelok, если я правильно понял, вам нужно отобразить кружочки по заданным координатам. Объявите класса VM
CB окна полностью очистите
И вот такая разметка XAML:
1 |
1006 / 625 / 212 Регистрация: 08.08.2014 Сообщений: 1,943 |
|
11.01.2020, 13:42 [ТС] |
4 |
Элд Хасп
0 |
Модератор 13812 / 10018 / 2668 Регистрация: 21.04.2018 Сообщений: 29,816 Записей в блоге: 2 |
|
11.01.2020, 13:49 |
5 |
Эллипсы там не подходят, т.к. они к точке привязываются левым верхним углом, а мне нужно чтобы центрировались. Это не проблема. Я просто показал пример реализации.
Мне нужно отобразить коллекцию произвольных объектов по заданным координатам. Потому и использовал ‘CompositeCollection’. Но у вас в шаблоне только EllipseGeometry ! Вы вопросы свои толком объясняйте.
1 |
1006 / 625 / 212 Регистрация: 08.08.2014 Сообщений: 1,943 |
|
11.01.2020, 14:03 [ТС] |
6 |
Как вы собираетесь показывать иные фигуры Для каждого типа фигуры свой Просто изначальный вопрос был именно про ошибку. Т.е. не понятно, почему пример работает корректно, но при этом в дебаг каждый раз выдаёт ошибку. Потому свёл пример к самому минимуму.
0 |
Элд Хасп Модератор 13812 / 10018 / 2668 Регистрация: 21.04.2018 Сообщений: 29,816 Записей в блоге: 2 |
||||||||
11.01.2020, 15:00 |
7 |
|||||||
Решение
Т.е. не понятно, почему пример работает корректно, но при этом в дебаг каждый раз выдаёт ошибку.
Это свойство только для чтения и инициализируется ещё до работы конструктора экземпляра. У вас свойство неинициализировано
Инициализируется оно после вызова
1 |
Доброго времени суток, никак не могу понять почему нет привязки, буду благодарен за любую критику и наставления, спасибо.
Model:
public class Data : ViewModelBase
public DateTime BeginDate { get; set; }
public DateTime EndDate { get; set; }
public bool ServerState { get; set; }
public TimeSpan ServerTimeSpan { get; set; }
public ObservableCollection<Terminal> Terminals { get; set; }
public class Terminal : ViewModelBase
public string Protocol { get; set; }
public string SerialId { get; set; }
public string SimNumber { get; set; }
public string ConnectionTime { get; set; }
public ObservableCollection<Sensor> Sensors;
public class Sensor : ViewModelBase
public string Type { get; set; }
public dynamic Value { get; set; }
ViewModel:
public class ViewModel : ViewModelBase
{
private Data Data;
public Data _data
{
get { return Data; }
set
{
if (Data != value)
{
Data = value;
NotifyPropertyChanged("Data");
}
}
}
public DelegateCommand OpenFileCommand { get; set; }
public ViewModel()
{
OpenFileCommand = new DelegateCommand(obj => OpenFileExecute(), obj => true);
}
private async void OpenFileExecute()
{
var openFileDialog = new OpenFileDialog();
var dialogResult = openFileDialog.ShowDialog();
if (!dialogResult.HasValue || !dialogResult.Value)
return;
var path = openFileDialog.FileName;
var xmlParser = new XmlParser();
var data = await xmlParser.ParseFile(path);
_data = data;
}
View:
<Button Content="Button" HorizontalAlignment="Left" Margin="269,347,0,0" VerticalAlignment="Top" Width="75" Command="{Binding OpenFileCommand}"/>
<DataGrid Name="Terminals" AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="10,158,0,0" VerticalAlignment="Top" Height="243" Width="254" SelectedItem="{Binding _data.SelectedTerminal}" ItemsSource="{Binding _data.Terminals}"/>
<DataGrid Name="Sensors" AutoGenerateColumns="False" HorizontalAlignment="Left" Margin="349,222,0,0" VerticalAlignment="Top" Height="158" Width="169" RenderTransformOrigin="0.311,0.278" ItemsSource="{Binding _data.SelectedTerminal.Sensors}"/>
Тут привязываю контекст:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new ViewModel.ViewModel();
}
}
Кстати, Output не ругается ни на что.
Связывание данных:
Отладка связывания данных
Поскольку вычисление привязки данных осуществляется во время исполнения программы, и в случае неудачи ошибки не генерируются, иногда становится очень сложно отследить неправильную привязку. Эта проблема может возникать по разным причинам, но чаще всего, если вы пытаетесь привязать несуществующее свойство либо потому что вы неправильно запомнили его название, либо просто допустили ошибку в его написании. Вот пример:
<Window x:Class="WpfTutorialSamples.DataBinding.DataBindingDebuggingSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataBindingDebuggingSample" Height="100" Width="200">
<Grid Margin="10" Name="pnlMain">
<TextBlock Text="{Binding NonExistingProperty, ElementName=pnlMain}" />
</Grid>
</Window>
Окно вывода
Прежде всего вам необходимо посмотреть на Окно вывода (Output window) Visual Studio. Оно должно быть расположено в нижней части главного окна Visual Studio (вы можете сделать его активным используя сочетание клавиш [Ctrl+Alt+O]. Здесь отображаются выходные данные, полученные от отладчика, но при запуске вышеупомянутого примера, среди этих данных вам нужно обнаружить строку, похожую на эту:
System.Windows.Data ошибка: 40: BindingExpression ошибка пути: ‘NonExistingProperty’ свойство не найдено в объекте Grid, имя которого ‘pnlMain’.
Исключение BindingExpression:Path=NonExistingProperty; DataItem=’Grid’ (Name=’pnlMain’);
целевой элемент ‘TextBlock’ (Name=»); целевое свойство ‘Text’ (тип ‘String’)
Это громоздкое сообщение может показаться избыточным, в основном из-за того что в нём отсутствуют разрывы строк, но самая важная часть содержится вот здесь:
Свойство «NonExistingProperty» не найдено в «объекте» «Grid» (Name = «pnlMain») ».
Это говорит о том, что вы попытались применить свойство с именем «NonExistingProperty» для объекта типа Grid с именем pnlMain. Теперь сообщение стало достаточно понятным, и оно должно помочь вам исправить имя свойства либо привязать существующий объект, если возникла проблема такого рода.
Изменение уровня диагностической информации (trace level)
Ошибку в вышеприведённом примере легко исправить, так как для WPF было понятно, что мы пытались сдеалать и почему это не сработало. Но давайте рассмотрим следующий пример:
<Window x:Class="WpfTutorialSamples.DataBinding.DataBindingDebuggingSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataBindingDebuggingSample" Height="100" Width="200">
<Grid Margin="10">
<TextBlock Text="{Binding Title}" />
</Grid>
</Window>
Здесь мы пытаемся сделать привязку к свойству «Title», но какого объекта? Как обсуждалось в главе, посвящённой контексту данных, WPF использует свойство DataContext элемента TextBlock, которое наследуется вниз по иерархии элементов управления, но в этом примере мы забыли задать контекст данных. Это фактически означает, что мы пытаемся получить свойство объекта NULL. WPF предположит, что эта привязка абсолютно корректна, но объект просто пока не был инициализирован, и не будет сообщать об этом. Если вы запустите этот пример и посмотрите на окно Output, вы не увидите ошибок привязки данных.
Однако в случаях, если это поведение программы вам не подходит, существует возможность заставить WPF сообщать вам о возникающих проблемах привязки данных. Этого можно добиться установкой TraceLevel объекта PresentationTraceSources, которые находятся в пространстве имён System.Diagnostics:
<Window x:Class="WpfTutorialSamples.DataBinding.DataBindingDebuggingSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
Title="DataBindingDebuggingSample" Height="100" Width="200">
<Grid Margin="10">
<TextBlock Text="{Binding Title, diag:PresentationTraceSources.TraceLevel=High}" />
</Grid>
</Window>
Обратите внимание, мы добавили ссылку на пространство имён System.Diagnostics в заголовке окна и затем задали свойство для привязки данных. В результате WPF будет выводить информацию об этой привязке в окне Output:
System.Windows.Data Warning: 55 : Created BindingExpression (hash=2902278) for Binding (hash=52760599)
System.Windows.Data Warning: 57 : Path: 'Title'
System.Windows.Data Warning: 59 : BindingExpression (hash=2902278): Default mode resolved to OneWay
System.Windows.Data Warning: 60 : BindingExpression (hash=2902278): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 61 : BindingExpression (hash=2902278): Attach to System.Windows.Controls.TextBlock.Text (hash=18876224)
System.Windows.Data Warning: 66 : BindingExpression (hash=2902278): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=2902278): Found data context element: TextBlock (hash=18876224) (OK)
System.Windows.Data Warning: 70 : BindingExpression (hash=2902278): DataContext is null
System.Windows.Data Warning: 64 : BindingExpression (hash=2902278): Resolve source deferred
System.Windows.Data Warning: 66 : BindingExpression (hash=2902278): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=2902278): Found data context element: TextBlock (hash=18876224) (OK)
System.Windows.Data Warning: 70 : BindingExpression (hash=2902278): DataContext is null
System.Windows.Data Warning: 66 : BindingExpression (hash=2902278): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=2902278): Found data context element: TextBlock (hash=18876224) (OK)
System.Windows.Data Warning: 70 : BindingExpression (hash=2902278): DataContext is null
System.Windows.Data Warning: 66 : BindingExpression (hash=2902278): Resolving source
System.Windows.Data Warning: 69 : BindingExpression (hash=2902278): Found data context element: TextBlock (hash=18876224) (OK)
System.Windows.Data Warning: 70 : BindingExpression (hash=2902278): DataContext is null
System.Windows.Data Warning: 66 : BindingExpression (hash=2902278): Resolving source (last chance)
System.Windows.Data Warning: 69 : BindingExpression (hash=2902278): Found data context element: TextBlock (hash=18876224) (OK)
System.Windows.Data Warning: 77 : BindingExpression (hash=2902278): Activate with root item <null>
System.Windows.Data Warning: 105 : BindingExpression (hash=2902278): Item at level 0 is null - no accessor
System.Windows.Data Warning: 79 : BindingExpression (hash=2902278): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 87 : BindingExpression (hash=2902278): TransferValue - using fallback/default value ''
System.Windows.Data Warning: 88 : BindingExpression (hash=2902278): TransferValue - using final value ''
Изучив данный список событий, мы сможем понять весь процесс, который происходит в WPF при поиске нужного значения для элемента TextBlock. Мы видим несколько безуспешных попыток определить контекст данных (DataContext), что в конечном итоге приводит к использованию значения по умолчанию {DependencyProperty.UnsetValue}, которое транслируется в пустую строку.
Использование настоящего отладчика
Приём, приведённый выше, можно использовать для диагностики ошибок привязки данных, но в некоторых случаях проще и удобнее работать с настоящим отладчиком. Привязка данных по умолчанию не поддерживает отладку, так как она происходит в глубинах WPF, но используя конвертер, описанный в предыдущей главе, мы можем внедриться в этот процесс и пройти его по шагам. На самом деле вам не нужен конвертер, который бы делал что-нибудь полезное, нам просто нужно войти в процесс привязки, а этого позволит добиться и фиктивный конвертер:
<Window x:Class="WpfTutorialSamples.DataBinding.DataBindingDebuggingSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:self="clr-namespace:WpfTutorialSamples.DataBinding"
Title="DataBindingDebuggingSample" Name="wnd" Height="100" Width="200">
<Window.Resources>
<self:DebugDummyConverter x:Key="DebugDummyConverter" />
</Window.Resources>
<Grid Margin="10">
<TextBlock Text="{Binding Title, ElementName=wnd, Converter={StaticResource DebugDummyConverter}}" />
</Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Data;
using System.Diagnostics;
namespace WpfTutorialSamples.DataBinding
{
public partial class DataBindingDebuggingSample : Window
{
public DataBindingDebuggingSample()
{
InitializeComponent();
}
}
public class DebugDummyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Debugger.Break();
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Debugger.Break();
return value;
}
}
}
В файле Code-behind мы создаём конвертер DebugDummyConverter. В методах Convert() и ConvertBack() мы вызываем метод Debugger.Break(), что приводит к такому же эффекту, что и установка точки прерывания программы в Visual Studio, с последующим возвратом неизменённого значения, полученного нами ранее.
В файле разметки мы добавляем ссылку на наш конвертер в ресурсах окна и затем используем его для привязки данных. В реальном приложении следует описывать конвертер в отдельном файле и добавлять ссылку на него в файле App.xaml, чтобы его можно было использовать в разных окнах приложения без необходимости создания ссылки в каждом окне, но для данного примера нам подойдёт и используемый подход.
Если вы запустите этот пример, вы увидите, что отладчик остановится , как только WPF попытается получить значение заголовка Window (Title). Вы можете проверить значение, переданное методу Convert(), или даже изменить его перед обработкой, используя стандартные возможности отладки Visual Studio.
Если отладчик не останавливается в нужной точке, это означает, что конвертер не используется. Обычно это означает, что у вас неправильная привязка, которую можно диагностировать и исправить с помощью методов, описанных в начале этой статьи. Трюк с фиктивным конвертером предназначен только для проверки правильности выражения привязки.
This article has been fully translated into the following languages:
-
Bulgarian
-
Chinese
-
Danish
-
French
-
German
-
Italian
-
Japanese
-
Polish
-
Portuguese
-
Russian
-
Spanish
-
Swedish
-
Turkish
-
Vietnamese
Is your preferred language not on the list? Click here to help us translate this article into your language!
Это ошибка привязки данных
Самый простой способ прочитать их — разбить его на двоеточие/полуколоны и прочитать его назад
Ошибка System.Windows.Data: 40: Ошибка пути BindingExpression: ‘Sender’ свойство не найдено в ‘object’ » Char ‘(HashCode = 6619237)’. BindingExpression: Path = Sender; DataItem = ‘Char’ (HashCode = 6619237); целевым элементом является «TextBlock» (Name= »); target свойство — «Текст» (тип ‘String’)
- target свойство — «Текст» (тип «String» )
- целевым элементом является «TextBlock» (Name= »);
- BindingExpression: Path = Sender;
- DataItem = ‘Char’ (HashCode = 6619237);
- Свойство «Отправитель» не найдено в ‘object’ » Char ‘(HashCode = 6619237)’.
- Ошибка пути BindingExpression:
- Ошибка System.Windows.Data: 40:
1 сообщает вам, что существует свойство Text
, вызывающее ошибку
2 сообщает вам, что свойство Text находится в элементе <TextBlock>
3 сообщает вам, что проблема с привязкой, вызывающая проблему, составляет {Binding Path=Sender}
4 сообщает, что DataItem/DataContext за элементом <TextBlock>
является элементом типа данных Char
5 сообщает вам фактическую проблему с этим: для объекта типа Char
нет свойства с именем Sender
6 просто сообщает вам об ошибке привязки
7 Я не знаю, что это значит
Поскольку я вижу, что у вас есть общедоступное свойство с именем Sender
в вашем классе Message
, и ясно, что Message
не Char
, его очевидно, что ваш DataContext
для каждого элемента неверен.
Поскольку он установлен в Char
, наиболее вероятной причиной является привязка к строке, а DataContext
для каждого элемента — символ в этой строке.
И, конечно, ItemsSource="{Binding Source=Messages}
означает, что вы изменяете свойство привязки Source
от текущего DataContext
до string
. И строки — это только массивы символов, поэтому это означает, что вы привязываетесь к массиву символов { M, e, s, s, a, g, e, s }
Если вы измените свойство Source
на свойство Path
, тогда оно будет корректно читать DataContext.Messages
и должно работать.
<ListView ItemsSource="{Binding Path=Messages}" ... />
(Слово Path
здесь необязательно, так как если вы не укажете имя свойства, тогда привязка предполагает, что это значение для свойства Path
)
В качестве примечания, я не вижу, чтобы вы установили свой DataContext
в любом месте формы, и я не вижу общедоступного свойства Messages
.
Конструктор MainWindow
должен, вероятно, иметь строку кода, которая выглядит так, чтобы установить DataContext
в себя:
this.DataContext = this;
И вам, вероятно, понадобится публичное свойство для вашего ObservableCollection<Message> messages
, поэтому привязка ListView
может найти его:
public ObservableCollection<Message> Messages
{
get { return messages; }
set { messages = value; }
}
Я не уверен, что их просто пропустили, или если вы не знали, что вам нужны были.
О, и если вы планируете изменить любой из этих связанных свойств и автоматически обновить пользовательский интерфейс, вы захотите реализовать INotifyPropertyChanged тоже:)
И так как я сейчас в учебном режиме, я решил, что должен также ссылаться на этот ответ:
Переход из Windows Forms в WPF
Я бы очень рекомендовал прочитать его (и связанные статьи), если вы новичок в работе WPF, и переходите от Winforms к WPF. Кажется, что вы:)