System windows data error 40

Igorian

1 / 1 / 0

Регистрация: 22.11.2013

Сообщений: 19

03.11.2015, 12:21. Показов 9289. Ответов 8

Метки wpf (Все метки)


Здравствуйте, у меня есть Главное окно, есть 2 контрола. В 1-ом контроле у меня listBox, во втором label, соединяю я их в MainWindow. Так вот, мне нужно, чтобы в главном окне я нажимал на listBox и у меня имя, выбранное в ListBox-е отображалось в Label.

Список выводит, но при нажатии ничего не происходит, а пишется ошибка
System.Windows.Data Error: 40 : BindingExpression path error: ‘name’ property not found on ‘object’ »UserControl1ViewModel’ (HashCode=48860040)’. BindingExpression:Path=name; DataItem=’UserControl1ViewModel’ (HashCode=48860040); target element is ‘UserControl1′ (Name=’me’); target property is ‘SelectedName’ (type ‘String’)

Кто-нибудь помогите, плз!

1.Главное окно —

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
 
            this.DataContext = new MainWindowViewModel();
        }
    }
 
    class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        public string m_name;
 
        public string name
        {
            get { return m_name; }
            set
            {
                m_name = value;
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("name"));
            }
        }
    }

xaml к MainWindow

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<Window x:Class="MyTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        
        xmlns:uc="clr-MyTest"
        >
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="5*"/>
            <RowDefinition Height="6*"/>
        </Grid.RowDefinitions>
        <uc:UserControl1 Grid.Row="0" SelectedName="{Binding name, Mode=OneWayToSource}"/>
        <!--<Label Content="{Binding name}" Grid.Row="1"/>-->
        <uc:UserControl2 Grid.Row="1" DisplayName="{Binding name}"/>
    </Grid>
</Window>

,
есть 2 контрола — 1 Контрол ->

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
 
            this.DataContext = new UserControl1ViewModel();
            //lb.ItemsSource = new List<string>() { "Misha", "Masha", "Kosta" };
            //lb.ItemsSource = new ObservableCollection<string>(new List<string>() { "Misha", "Masha", "Kosta" });
        }
 
        public static DependencyProperty SelectedNameProperty = DependencyProperty.Register(
            "SelectedName",
            typeof(string),
            typeof(UserControl1),
            new UIPropertyMetadata(null)
            );
 
        public string SelectedName
        {
            get { return this.GetValue(SelectedNameProperty) as string; }
            set { SetValue(SelectedNameProperty, value); }
        }
    }
 
    public class UserControl1ViewModel : INotifyPropertyChanged// DependencyObject
    {
        public event PropertyChangedEventHandler PropertyChanged;
 
        public UserControl1ViewModel()
        {
            getSetToListBox = new ObservableCollection<string>(new List<string>() { "Misha", "Masha", "Kosta" });
            
            if(PropertyChanged!=null)
                PropertyChanged(this, new PropertyChangedEventArgs("getSetToListBox"));
        }
 
        public ObservableCollection<string> getSetToListBox { get; private set; }
 
        //public string name
        //{
        //    get;
        //    set;
        //}
    }

,
xaml 1 контрола ->

XML
1
2
3
4
5
6
7
8
9
10
11
12
<UserControl x:Class="MyTest.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             x:Name="me">
    <Grid>
        <ListBox ItemsSource="{Binding getSetToListBox}" SelectedItem="{Binding SelectedName, ElementName=me, Mode=OneWayToSource}"/>
    </Grid>
</UserControl>

,
2-ой контрол ->

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public partial class UserControl2 : UserControl
    {
        public UserControl2()
        {
            InitializeComponent();
        }
 
        public static DependencyProperty DisplayNameProperty = DependencyProperty.Register(
            "DisplayName",
            typeof(string),
            typeof(UserControl2)
            );
 
        public string DisplayName
        {
            get { return this.GetValue(DisplayNameProperty) as string; }
            set { SetValue(DisplayNameProperty, value); }
        }
    }

,
xaml 2контрола ->

XML
1
2
3
4
5
6
7
8
9
10
11
12
<UserControl x:Class="MyTest.UserControl2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             x:Name="me"
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Label Content="{Binding DisplayName, ElementName=me, Mode=OneWay}"/>    
    </Grid>
</UserControl>



0



amarf

Жуткая тВарЬ

393 / 328 / 135

Регистрация: 06.02.2015

Сообщений: 962

Записей в блоге: 1

03.11.2015, 14:19

XML
1
<uc:UserControl1 Grid.Row="0" SelectedName="{Binding name, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>



1



1 / 1 / 0

Регистрация: 22.11.2013

Сообщений: 19

03.11.2015, 23:09

 [ТС]

Неа, не помогает, теперь вылетает ошибка ->

System.Windows.Data Error: 40 : BindingExpression path error: ‘name’ property not found on ‘object’ »MainWindow’ (Name=»)’. BindingExpression:Path=name; DataItem=’MainWindow’ (Name=»); target element is ‘UserControl1′ (Name=’me’); target property is ‘SelectedName’ (type ‘String’)



0



Жуткая тВарЬ

393 / 328 / 135

Регистрация: 06.02.2015

Сообщений: 962

Записей в блоге: 1

04.11.2015, 20:56

Так перенесите свойство в клпасс окна… Вы вообще про привязку читали?

Добавлено через 6 минут
Так по ходу я дурак))} перечитал первый пост внимательно…. Вы когда создаёте ваш контрол сразу задаете ему вьюмодель в датаконтексте вот в ней привязка и пытается найти свойство, а надо искать в датаконтексте окна… Т.е. Либо убирайте из контрола датаконтекст, либо делаете привязку как в моем посте выше но только вместо nane пишем datacontext.name



1



Igorian

1 / 1 / 0

Регистрация: 22.11.2013

Сообщений: 19

05.11.2015, 18:57

 [ТС]

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

Вот написал ->

C#
1
<uc:UserControl1 Grid.Row="0" SelectedName="{Binding DataContext.name, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>

Ошибка исчезла, но проблема с передачей данных осталась. Т.е. если нажимаешь на строку таблицы 1Контрола, ничего не происходит во 2ом Контроле.

А как тогда должна инфа передаваться в этот 2ой контрол ->

C#
1
<uc:UserControl2 Grid.Row="1" DisplayName="{Binding name}"/>

Изначально я передавал данные из SelectedName(1Контрол) в name (Главного окна), затем из name(Главного окна) передавалось в DisplayName(2го Контрола). А теперь чего делать?

Сейчас из SelectedName(1Контрол) в DataContext.name (Главного окна), затем из … что куда должно передаться, чтоб отобразилось во 2омКонтроле?



0



Жуткая тВарЬ

393 / 328 / 135

Регистрация: 06.02.2015

Сообщений: 962

Записей в блоге: 1

05.11.2015, 20:20

Igorian, Вам быпочитать про mvvm, принципы построения слобосвязанных приложений и много чего еще, но это кучу времени потратите, но оно тогг стоит. Так, что если есть время то начните чтение с внедрения зависимостей ибо на этом принципе и паттерне стратегия уйма всего устроено… Ну естественно по wpf тоже надо читать, но не так много…

Я могу Вам накидать пример под Вашу задачу, только опишите что хотите получить от работы программы, применение юзерконтролов у вас не обоснованно и не нужно



1



1 / 1 / 0

Регистрация: 22.11.2013

Сообщений: 19

05.11.2015, 21:30

 [ТС]

Спасибо за инфу о том, что нужно почитать. Это я обязательно сделаю.

Насчет необоснованных контролов — да, я согласен, в этом примере они не нужны, но у меня есть приложение, в котором я использую avalonDock. Там нужны контролы, которые будут подгружаться в качестве отдельных окон и которые будут использоваться в разных местах.

А этот пример я взял для того, чтобы понять, как это дело работает.

Я делал все это дело без viewModel, все получилось, а вот когда я использую viewModel, вот ничего и не получается.

Задача у меня такая — Есть 2 Контрола: — 1Контрол — Таблица listBox/ListView(В ней выбирается строка для отображения во втором контроле), 2Контрол — Label, в который записывается просто имя , выбранное из первого контрола. И все это связано через MainWindow. Потом я вместо имени буду данные из базы закидывать и подружать
их в другие таблицы, а вот сейчас хотябы на самом простом примере понять.



0



Жуткая тВарЬ

393 / 328 / 135

Регистрация: 06.02.2015

Сообщений: 962

Записей в блоге: 1

06.11.2015, 10:17

В общем накидал пример, единственное, что я решил сделать с использованием аггрегатора событий из библиотеки призм (короче надо устанавливать через Nuget пакет Prism.PubSubEvents) — зато он убирает кучу всякой хрени в которой можно запутаться (в частности излишнюю управляющую вьюмодель и колбэки с подписками)

Так же прощу обратить внимание, что есть специальный класс Boot в котором назначаются вьюмодели для наших контролов — ТАК ДЕЛАТЬ НЕЛЬЗЯ — но поскольку я не стал нагружать проект еще и контейнером внедрения зависимости, мне показалось, что такой подход будет понятнее…

AggregateMVVM.zip

П.С. На самом деле «по настоящему» все делается немножко сложнее (и в тоже время легче если знаешь материал), но для этого надо знать хотя бы про Внедрение зависимостей в .Net и несколько паттернов



1



1 / 1 / 0

Регистрация: 22.11.2013

Сообщений: 19

07.11.2015, 10:04

 [ТС]

amarf, Спасибо огромное за написанный вами пример!
Буду разбираться…



0



I keep getting this Error:
System.Windows.Data Error: 40 :
BindingExpression path error:

System.Windows.Data Error: 40 : BindingExpression path error:

  • ‘ViewModels’ property not found on ‘object’ »MainWindow’ (Name=»)’.

  • BindingExpression:Path=ViewModels.EventViewModel.EventName;

  • DataItem=’MainWindow’ (Name=»);

  • target element is ‘ComboBox’ (Name=’EventNameComboBox’);

  • target property is ‘SelectedItem’ (type ‘Object’)

MainWindow.XAML

    <ComboBox Name="EventNameComboBox"
              DisplayMemberPath="EventName"
              HorizontalContentAlignment="Center"
              ItemsSource="{Binding Path=EventViewModels}"
              materialDesign:HintAssist.Hint="Select an Event"
              SelectionChanged="EventNameComboBox_SelectionChanged"
              Width="400">
        <ComboBox.SelectedItem>
            <Binding Path="ViewModels.EventViewModel.EventName" UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <validationRules:EventNameValidationRule ValidatesOnTargetUpdated="True"/>
                </Binding.ValidationRules>
            </Binding>
        </ComboBox.SelectedItem>
        <ComboBox.ItemsPanel>
         <ItemsPanelTemplate>
             <VirtualizingStackPanel/>
         </ItemsPanelTemplate>
        </ComboBox.ItemsPanel>
    </ComboBox>

EventNameValidationRule.cs

public class EventNameValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        string eventName = value == null ? "" : value.ToString();

        return string.IsNullOrEmpty(eventName)
            ? new ValidationResult(false, "Please select a Event")
            : ValidationResult.ValidResult;
    }
}

Finally,

EventViewModel.cs

public class EventViewModel : INotifyPropertyChanged
{
    private int _eventId;
    private string _eventName;


    public int EventId
    {
        get { return _eventId; }
        set
        {
            _eventId = value;
            OnPropertyChanged("EventId");
        }

    }

    public string EventName
    {
        get { return _eventName; }
        set
        {
            _eventName = value;
            OnPropertyChanged("EventName");
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

I’m not sure what is going on.

UPDATE

MainWindow.xaml.cs

private List<EventViewModel> _eventViewModels;

public List<EventViewModel> EventViewModels
{
    get { return _eventViewModels; }
    set { _eventViewModels = value; OnPropertyChanged("EventViewModels"); }
}

public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}


public MainWindow()
{
    InitializeComponent();

    EventViewModels = new List<EventViewModel>();
    int year = 2008;
    for (int i = 1; i <= 10; i++)
    {
        EventViewModel viewModel = new EventViewModel();
        viewModel.EventId = i;
        viewModel.EventName = $"{year} Test Event";

        ++year;

        EventViewModels.Add(viewModel);
    }

    DataContext = this;
} 

Skip to content



Navigation Menu

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

Appearance settings

Description

I see a lot of these in the console when running AssessingPeoplesSkills project (see below), but not sure if it is actually affecting anything… the program seems to run fine.

System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=62400565)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=62400565); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=29593675)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=29593675); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=25269681)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=25269681); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=5503354)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=5503354); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=59434866)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=59434866); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=19545759)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=19545759); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=35563764)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=35563764); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=35876092)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=35876092); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=21777794)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=21777794); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=16901523)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=16901523); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=45904861)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=45904861); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=16441830)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=16441830); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=9774622)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=9774622); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=2733199)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=2733199); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)
System.Windows.Data Error: 40 : BindingExpression path error: ‘IsRecentlyModified’ property not found on ‘object’ »DictionaryEntryPart’ (HashCode=21296519)’. BindingExpression:Path=IsRecentlyModified; DataItem=’DictionaryEntryPart’ (HashCode=21296519); target element is ‘ListViewItem’ (Name=»); target property is ‘NoTarget’ (type ‘Object’)
System.Windows.Data Error: 25 : Both ‘ContentTemplate’ and ‘ContentTemplateSelector’ are set; ‘ContentTemplateSelector’ will be ignored. ContentPresenter:’ContentPresenter’ (Name=»)

System windows data error 40: ошибка привязки пути BindingExpression

На чтение4 мин

Опубликовано

Обновлено

Один из распространенных видов ошибок в Windows приложениях, связанных с работой с данными, является System windows data error 40. Эта ошибка возникает, когда при попытке привязки значения к элементу управления происходит ошибка в разрешении конечного пути. В основном, это происходит из-за некорректных данных или неправильной структуры элемента управления.

Ошибка System windows data error 40 может быть вызвана различными причинами, такими как отсутствие необходимых данных, неправильное имя свойства в источнике данных или отсутствие необходимых разрешающих прав у пользователя. В любом случае, ошибка может привести к неработоспособности приложения или неправильному отображению данных на экране.

Для решения проблемы с ошибкой System windows data error 40, первым шагом будет проверка корректности данных, с которыми работает приложение. При необходимости, убедитесь, что данные существуют, корректно отформатированы и доступны для чтения. Также стоит проверить имя свойства в источнике данных и убедиться, что оно указано верно.

Если проблема не решается путем проверки данных, возможно, потребуется провести дополнительные действия, такие как изменение прав доступа к файлам или проверка работоспособности устройства, к которому подключено приложение. Если вы не уверены в правильности этих действий, рекомендуется обратиться к специалистам или поискать подробную информацию в документации.

Что такое ошибка System windows data error 40?

Ошибка System windows data error 40 относится к проблемам, связанным с привязкой пути BindingExpression в Windows-системе. Эта ошибка может возникать при разработке приложений на платформе WPF (Windows Presentation Foundation) и указывает на проблемы с привязкой данных.

Когда разработчики создают пользовательский интерфейс в WPF, они могут использовать привязку данных для связи элементов пользовательского интерфейса со значениями из различных источников данных. Привязка пути BindingExpression — это механизм, который обеспечивает связь между элементом пользовательского интерфейса и данными, определенными в источнике данных.

Ошибка System windows data error 40 указывает на то, что возникла проблема при привязке пути BindingExpression, и данные не могут быть правильно связаны с элементом пользовательского интерфейса. Это может произойти, например, когда указанный путь привязки не существует или имеет неправильный формат.

Чтобы исправить ошибку System windows data error 40, разработчику необходимо выполнить несколько шагов:

  1. Убедитесь, что указанный путь привязки существует в источнике данных. Проверьте правильность названия свойств и элементов в пути.
  2. Проверьте правильность синтаксиса пути привязки. Убедитесь, что вы используете правильные разделители и операторы для доступа к свойствам и элементам в пути.
  3. Проверьте права доступа к данным в источнике данных. Убедитесь, что данные, к которым вы пытаетесь получить доступ, доступны для чтения.
  4. Проверьте, что источник данных и элементы пользовательского интерфейса находятся в одном контексте привязки. Иногда неверное размещение элементов может привести к проблемам с привязкой пути.
  5. Проверьте ошибки в журнале событий или консоли разработчика для получения более подробной информации о проблеме. Иногда сообщения об ошибках могут указывать на конкретные проблемные места в коде.

В случае, если проблема с привязкой пути BindingExpression не удается решить, рекомендуется обратиться к документации по WPF или обратиться за помощью к сообществу разработчиков. Они могут предоставить дополнительные советы и решения для данной ошибки.

Причины возникновения ошибки System windows data error 40

Ошибка System windows data error 40 может возникнуть из-за различных причин, связанных с проблемами при привязке пути BindingExpression. Эта ошибка может возникнуть при разработке приложений на платформе Windows, использующих привязку данных для связи данных между элементами пользовательского интерфейса и их источником данных.

Одной из причин возникновения ошибки может быть неправильно заданное свойство привязки данных. Например, если свойство не существует или имеет неправильное имя, система не сможет найти путь привязки и выдаст ошибку.

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

Также, ошибка System windows data error 40 может возникнуть из-за некорректного типа данных. Если тип данных, используемый в привязке пути, не соответствует ожидаемому типу данных элемента пользовательского интерфейса, также будет выдана ошибка.

Еще одной возможной причиной является изменение контекста привязки данных. Если контекст привязки данных был изменен или не найден, возникает ошибка при привязке пути.

Для исправления ошибки System windows data error 40 необходимо внимательно проверить все участки кода, связанные с привязкой данных. Убедитесь, что свойства привязки данных заданы правильно, источники данных доступны и данные соответствуют ожидаемым типам данных.

Как исправить ошибку System windows data error 40?

Чтобы исправить ошибку System windows data error 40, можно попробовать следующие рекомендации:

  1. Перезапустите приложение: В некоторых случаях проблема может возникнуть из-за временного сбоя в работе приложения. Попробуйте закрыть приложение и перезапустить его снова. Это может помочь исправить ошибку.
  2. Обновите приложение: Проверьте, доступны ли обновления для вашего приложения. Возможно, разработчики выпустили исправления, которые помогут решить проблему с ошибкой System windows data error 40. Обновите приложение до последней версии.
  3. Обновите операционную систему: Убедитесь, что у вас установлена последняя версия операционной системы Windows. Иногда проблемы с привязкой данных могут возникать из-за устаревших компонентов операционной системы. Выполните обновление Windows и проверьте, исправилась ли ошибка.
  4. Проверьте свои данные: Если ошибка System windows data error 40 связана с конкретными данными или каким-то их аспектом, проверьте их на правильность и целостность. Возможно, данные повреждены или содержат ошибку, что приводит к возникновению ошибки привязки пути BindingExpression.
  5. Проверьте код приложения: Если вы разработчик приложения, внимательно изучите код, связанный с привязкой данных. Возможно, ошибка вызвана некорректной реализацией привязки данных. В этом случае вам потребуется исправить код, чтобы решить проблему.

Если ни одно из перечисленных выше решений не помогло исправить ошибку System windows data error 40, обратитесь за помощью к разработчику приложения или к поддержке операционной системы Windows. Они смогут предоставить дополнительные советы или решения для устранения этой проблемы.

Greetings;

I’m having difficulty using WPF’s support for Data Binding a generic List<> instance to a Read-Only DataGrid inside a Window.  To setup the Data Binding, I have the following in place in the code:

1.) I set the Window’s DataContext to a reference type of FormattedStackTrace exposed as a public property named StackTrace.  The DataContext is set in the Window’s class constructor in C# as follows:

        public CallStackDialog(Window owner,
               FormattedStackTrace stackTrace)
        {
            InitializeComponent();
            this.Owner = owner;

            StackTrace = stackTrace;
            DataContext = StackTrace;

            return;
        }

The instance of StackTrace is non-null, and I can access and view all of its property members through the StackTrace property as expected.  Likewise, the Window’s DataContext is a non-null value.

2.) The StackTrace property is implemented in the same window class as follows:

        private FormattedStackTrace formattedStackTrace;

        public FormattedStackTrace StackTrace
        {
            get
            {
                return formattedStackTrace;
            }

            set
            {
                formattedStackTrace = value;
                NotifyPropertyChanged("StackTrace");
            }
        }

3.) The FormattedStackTrace class contains an instance of List<OrderedCall> as an auto property named OrderedStackTrace.  I am trying to bind this collection as the ItemsSource for the DataGrid in the window. The relative members of the FormattedStackTrace,
which is the backing reference type for the Window’s DataContext, is as follows:

    public class FormattedStackTrace
    {
#region FormattedStackTrace Class Data Members & Auto-Properties

        private StackFrame[] sourceStackFrame;
        public MethodBase CallingMethod { get; private set; }
        public List<OrderedCall> OrderedStackTrace { get; private set; }

#endregion
    }

OrderedStackTrace is a List<OrderedCall>, where each List member is an instance of the following structure:

    public struct OrderedCall
    {
        public int Call;
        public string Method;
    }; 

At the point where the DataContext is set inside the parent Window’s class constructor, the OrderedStackTrace property is correct, in that it contains the expected number of OrderedCall instance values, and they can be viewed without issue inside any of the
Debugging tabs inside Visual Studio 2010, or inside the IDE’s Immediate Window:

    ? StackTrace.OrderedStackTrace == null
    false
    ? StackTrace.OrderedStackTrace.Count
    40
    ? StackTrace.OrderedStackTrace[39]
    {WPFEventHandling.OrderedCall}
        Call: 40
        Method: «WPFEventHandling.MainWindow.OnMousePointerEnteredButton(Object sender, MouseEventArgs e)»

4.) The DataGrid inside the Window I’m trying to bind to, StackTraceDataGrid, which is read only, is implemented in XAML as follows:

<DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" 
          Name="StackTraceDataGrid" IsReadOnly="True"
          AutoGenerateColumns="False" Margin="10" 
          ItemsSource="StackTrace.OrderedStackTrace">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Offest" 
         Binding="{Binding Call}" Width="60">
        </DataGridTextColumn>
        <DataGridTextColumn Header="Method" 
         Binding="{Binding Method}" Width="*">
        </DataGridTextColumn>
    </DataGrid.Columns>
</DataGrid>

When I build the solution containing this Window and  the child StackTraceDataGrid control, there are no errors nor compiler warnings. When I bring up the parent window that contains StakTraceDataGrid, the DataGrid and the two Text Columns, Offset and
Method, are rendered and formatted as expected, but each row in the DataGrid is empty.  When the Window is brought up, the following set of runtime messages appear for each pair of OrderedCall member values in each column for each row:

System.Windows.Data Error: 40 : BindingExpression path error: ‘Call’ property not found on ‘object’ »Char’ (HashCode=7471218)’. BindingExpression:Path=Call; DataItem=’Char’ (HashCode=7471218); target element is ‘TextBlock’ (Name=»); target property is ‘Text’
(type ‘String’)
System.Windows.Data Error: 40 : BindingExpression path error: ‘Method’ property not found on ‘object’ »Char’ (HashCode=7471218)’. BindingExpression:Path=Method; DataItem=’Char’ (HashCode=7471218); target element is ‘TextBlock’ (Name=»); target property is
‘Text’ (type ‘String’)

As far as I can tell, I think that my problem may lie in how I’ve defined the ItemsSource property for the DataGrid, and the Binding Path for each column for each instance of OrderedCall as I would like to have displayed in each row of the Grid.

I would really appreciate any corrections on how to resolve the BindingExpression path errors I’m seeing at runtime, as well as any background informatio on what each DataGrid Column is expecting for a Binding Path for each item in each row of the DataGrid.

Thank you in advance for your time and help, and I look forward to hearing from you soon.


This article covers many techniques you can use to troubleshoot and debug your WPF application, including binding errors, exception handling, inspecting the VisualTree and logging.

Table of Contents

  • Introduction
  • Binding Errors
    • 1. Changing Trace Level for All in Options
    • 2. Changing Trace Level on a Specific Binding
  • WPF Tree Visualizer
    • Other inspection tools
  • Debuging Your Code
  • Inner Exceptions
  • Unhandled Exceptions
    • Application.DispatcherUnhandledException
    • AppDomain.CurrentDomain.UnhandledException
    • TaskScheduler.UnobservedTaskException
    • The catch-all Unhandled Handler!
    • Drilling down to include the Inner Exceptions
  • Commenting Out and Binary Chopping
  • Is It Reproducable?
  • Logging
    • Logging Level
    • Repository Choice
    • Why Reinvent the Wheel
      • Log4Net
      • ELMAH
      • NLog
      • NuGet
  • See Also
  • Community Resources

Introduction

Windows Presentation Foundation (WPF) is a joy to develop rich user experiences with. Animations, bindings, reskinnable codeless interfaces, all backed up with traditional .Net programming all make for a very rapid development cycle. However, when something
goes wrong in that autogenerated super-sexy front-end, it is not always clear where the problem is.

This article will cover some of the methods for analyzing your WPF application, troubleshooting issues, and debugging seemingly obscure errors. 


Return to Top


Binding Errors

When an error occurs in the binding framework, the notification is usually «silent», in that is doesn’t pop up an error dialog to the user. The error is instead displayed in the
Output Window of Visual Studio. Although the errors seem obscure at first, there are only a few common ones and they are quite helpful messages. 

Below are some typical errors and an explanation for each. 


System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''. BindingExpression:Path=PartIds; DataItem=null; target element is 'ComboBox'
(Name=''); target property is 'ItemsSource' (type 'IEnumerable')


This is a ComboBox inside a DataGridTemplateColumn. I am binding its ItemsSource to a property called PartIds. 

It is erroring when looking for the binding source, in other words the physical object to find the property on.

In this example, the error was because the source is a Window, not a UserControl. 


"System.Windows.Data Error: 40 : BindingExpression path error: 'MyStringOptionz' property not found on 'object' ''MainWindow' (Name='Window')'. BindingExpression:Path=MyStringOptionz; DataItem='MainWindow' (Name='Window'); target element is 'ComboBox'
(Name=''); target property is 'ItemsSource' (type 'IEnumerable')"


This is when the property name in the binding expression is wrong, or the property does not exist in the source object.

In this example, the property name was misspelled with a ‘z’.

Sometimes you will need a more detailed debugging output for binding. There are two ways to do this.

1. Changing Trace Level for All in Options

Click the Visual Studio menu Tools / Options, then open
Debugging and Output Window. In there you can change the
DataBinding output settings to Verbose or
All
.

(click to enlarge)

2. Changing Trace Level on a Specific Binding

If you increase the trace level that way, you will get a WHOLE LOAD of messages for everything. Far better to target the specific binding where the error is. To do this, you can call on an Attached Property PresentationSources.TraceLevel and set it for just
the one binding.

<ComboBox
ItemsSource="{Binding PartIdz,
PresentationTraceSources.TraceLevel=High
, RelativeSource={RelativeSource AncestorType=Window}}"
. . . />

For more information on the Trace Levels and what they represent,
read here. 


Return to Top


WPF Tree Visualizer

The WPF Tree Visualizer comes built into Visual Studio, and is an essential tool to know about.

With it, you can break into the Visual Tree and inspect the actual generated elements and their properties.

To use a Visualizer, you click on the magnifying glass next to a variable name in
DataTips, a Watch window, or in the
Autos, Locals, or
Quick Watch
window.

If you are visualizing a string object for example, you get a big grey text window. However, if you visualize a FrameworkElement, you get the WPF Tree Visualizer.

(click to enlarge) 

For a Quick Start on how to use the WPF TV, try this :
Debugging WPF — WPF Tree Visualizer + Helper Class

It also supplies a handy Attached Property you can drop in anywhere, without messing your code. 

The WPF Tree Visualizer is great for inspecting the VisualTree, but if you want to
change any of the properties, you have to look at the «Locals» tab, as shown below.

(click to enlarge)

Other inspection tools

WPF Tree Visualizer is usually enough for the experienced developer to find the problem, however there are plenty of tools around if you prefer to defer.

  • WPF Inspector
  • UI Spy (in Microsoft Windows SDK)
  • Snoop
  • XamlIT
  • Mole
  • Pistachio


Return to Top


Debuging Your Code

Apart from the WPF Tree Visualiser, the debugger in WPF applications is the main way to break into your application, trace through and follow program execution to the point of failure.

This is all standard Visual Studio stuff, and I won’t waste time here reproducing what is available elsewhere:

  • Debugging in Visual Studio
  • Debugging Managed Code
  • Debugging, Tracing, and Profiling


Return to Top


Inner Exceptions

When your application raises an exception, and you are debugging in Visual Studio, you get the usual error dialog with the details. However, when the error is a XAML error, it is most frequently buried deeper in the exception details.

Within each exception is an Inner Exception, which is just another exception, but from a layer further down. If XAML throws an error about a missing resource, it re-raises the error as a meaningless «XAML Markup error». When you drill down deeper, you find
what resource the actual error relates to.

Josh Smith wrote best documents the joy of inner exceptions  here. 


Return to Top


Unhandled Exceptions

It is impossible to protect against every possible fault that could happen, when your application is «out in the wild». 

There are however, ways to try and improve on the standard Windows error dialogue, and stack dump, which will help you find the fault.

When an exception is unhandled by your application, there are several Unhandled Exception events that you can tap into and handle.

You can download and test all five handlers here :
Handling Unhandled Exceptions in WPF (The most complete collection of handlers)

Application.DispatcherUnhandledException

This is triggered when the UI thread causes an unhandled exception. You can attach a handler to it either in App.xaml

<Application
x:Class="MyProject.App"

  StartupUri="MainWindow.xaml"
DispatcherUnhandledException="App_DispatcherUnhandledException">

 <Application.Resources
/>

</Application>

… or App.xaml.cs

namespace
MyProject

{

 public
partial
class
App : Application

 {

  public
App()

  {

   DispatcherUnhandledException +=
new
System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);

  }

What you get in the handler arguments is a standard exception. Handle as you like, preferably write it to a permissions safe file location.

You can also set e.Handled to true if you want to try to overcome the error and move on

void
App_DispatcherUnhandledException(object
sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)

{

 ProcessError(e.Exception);

 e.Handled =
true;

}

Sometimes the error is too severe, and your application still crashes. But at least you have hopefully captured something useful, before it did.

AppDomain.CurrentDomain.UnhandledException

If the error is not on the UI thread, then the previous handler won’t catch it. It is solely for the Dispatcher thread. To capture errors on any other thread, you need this second one.

This handler is attached in the Startup event handler, which can again be hooked into from mark-up:

<Application
x:Class="UnhandledExceptionHandler.App"

  StartupUri="MainWindow.xaml"
Startup="App_Startup">

 <Application.Resources
/>

</Application>

… or in code:

namespace
MyProject

{

 public
partial
class
App : Application

 {

  public
App()

  {

   Startup +=
new
StartupEventHandler(App_Startup);

  }

  void
App_Startup(object
sender, StartupEventArgs e)

  {

   AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

  }

  void
CurrentDomain_UnhandledException(object
sender, UnhandledExceptionEventArgs e)

  {

   var exception = e.ExceptionObject
as
Exception;

   ProcessError(exception);

   if
(e.IsTerminating)

  MessageBox.Show("Goodbye world!");

  }

Notice this uses an ExceptionObject, which is derived from Exception, so we can simply cast it back, for a generic exception handler, as shown below.

Also notice the ExceptionObject has an IsTerminating flag.

TaskScheduler.UnobservedTaskException

This exception happens when a Task has an «unobserved exception», and is about to trigger the «exception escalation policy», which by default
terminates the process.

namespace
MyProject

{

 public
partial
class
App : Application

 {

  public
App()

  {

   TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

  }

Again, we can try to prevent crashing, in this case by calling the e.SetObserved method, which marks the exception as «observed» and prevents exception escalation towards a termination (crash). 

void
TaskScheduler_UnobservedTaskException(object
sender, UnobservedTaskExceptionEventArgs e)

{

 ProcessError(e.Exception);

 e.SetObserved();

}

The catch-all Unhandled Handler!

Putting those three handlers together, we get the following:

namespace
MyProject

{

 public
partial
class
App : Application

 {

  public
App()

  {

   DispatcherUnhandledException += App_DispatcherUnhandledException;

   TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;

   Startup +=
new
StartupEventHandler(App_Startup);

  }

  void
App_Startup(object
sender, StartupEventArgs e)

  {

   AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

  }

In the examples below, I show how to try and mark the exceptions as handled/observed, and continue execution. However, you may just want to close «gracefully», with a polite message, instead of an all-out crash.

One thing is certain, you will probably want a unified way of handling the exceptions, wherever they come from, as shown below.

Drilling down to include the Inner Exceptions

As mentioned before, the real reason for an error could be buried several layers down in Inner Exceptions. The three handlers above shared one error logging method, shown below, which iterates down till there are no more Inner Exceptions.

private
void
ProcessError(Exception exception)

{

 var error =
"Exception = "
+ exception.Message;

 while(exception.InnerException !=
null)

 {

  exception = exception.InnerException;

  error +=
" : Inner Exception = "
+ exception.Message;

 }

 //This is where you save to file.

 MessageBox.Show(error);

}

Early attention to error handling in your application will always help production, because most bugs occur during development.

See Logging below.


Return to Top


Commenting Out and Binary Chopping

If a bug in your application is being particularly hard to find, there may be only one way left to find the culprit. It’s very simple, and is often simply the fastest way to drill down to the offender.

The method is simply to remove (or comment out) sections of your code, or XAML, until you get execution PAST the error.

Then you start replacing parts of the removed code, until you find the exact control or method that is causing the problem.

It is referred to as binary chopping because you cut the code into two, to get past the error, then in two again, replacing half of the removed code, and so on until you get down to the offending code/xaml.

You can comment out huge chunks of your code or markup in Visual Studio with ctrl-k + c, then ctrl-k + u to uncomment. Both functions also available in the edit / advanced menu.

This is one of the advantages of writing your application to the MVVM design pattern. MVVM separates your UI (View) from the business logic supplied by the ViewModel, or the Model itself. This means the View is much more loosely coupled, and there are no
hooks from code-behind, acting directly on controls, like referring to controls by name (x:Name) like MyTextBox.Text = «hello». In MVVM the emphasis is all on the bindings, so commenting out half your XAML just means less binding requests, and commenting out
half your code/properties means more binding errors, but not a crash. 

Even an MVVM setup can have problems when you try to comment out half the markup. Controls may be relying on other controls, with direct biding in XAML. So there is always a certain amount of «knock-on» effects that also need commenting out, but experience
often shows it is quite simply a very fast and effective way to find the sinner.

Just make sure you keep a copy of the original file (or have recently committed your code to source control) before such dramatic actions. Just in case you make an edit that looses your comment/cut history


Return to Top


Is It Reproducable?

When you hit a brick wall, many people turn to the
MSDN forums, for help and advice from other developers. Often, just the act of trying to put a problem into words for others to understand is equivalent to having a colleague look over your shoulder, which often catches those obvious «too close to the trees»
kind of mistakes that we all make.

However, if the problem isn’t obvious from your description, you will get a much quicker and accurate response from the forum if you supply a
reproduceable example of your problem in a few code snippets.

Quite often, when you try to reproduce the problem in a new project, you will often find the culpret anyway! 


Return to Top


Logging

The other age old method of tracing bugs in your application, both in development and once released, is to keep a log of messages from every notable step of your application.

If your bug is of a composite nature (comprising of several different causes), or developing after several iterations, or at an unknown point, you will need to build a picture of what is happening, before you can even know where to start. 

Logging Level

Writing comments and session data to a log file means scattering «WriteToLog» type methods throughout your code. It is therefore common to build a «LogLevel» parameter into your methods, allowing you to control the amount of spam that gets written. In a
published application you would only want to capture critical messages, but with a config file flag or startup parameter that allows you to crank up the debug logging (logging ALL messages), for a client that experiences a bug. 

Repository Choice

A log repository can be anything from a text file, to a database. One word of caution however. It is no good logging errors to a database if it was a database connection error. So file based logging for critical errors is strongly advised. Then you simply
have a check method on application startup, for any waiting critical error files, that may have been generated when the application crashed. You can then ‘process’ them (into a database, or send by email) and then delete.

It is as explained, quite simple to create your own logging architecture for your application. The key to success is to START EARLY! Don’t try to strap error handling or logging on later, as it will never be as useful as if you had started from the outset.
Also, the majority of bugs are caused during development anyway, so early attention to error handling and logging may take slightly longer to code, but will help speed up the overall production process. 

Why Reinvent the Wheel

You could have a lot of fun building your own error logging framework, that is thread safe and foolproof. Or if you’re pushed for time or more interested in higher things, why not just adopt a tried and tested logging framework. Here are some options, but
you should shop around, as new kids often come on the block. 

Log4Net

One of the most established frameworks. «log4net is a tool to help the programmer output log statements to a variety of output targets. In case of problems with an application, it is helpful to enable logging so that
the problem can be located. With log4net it is possible to enable logging at runtime without modifying the application binary. The log4net package is designed so that log statements can remain in shipped code without incurring a high performance cost. It follows
that the speed of logging (or rather not logging) is crucial. At the same time, log output can be so voluminous that it quickly becomes overwhelming. One of the distinctive features of log4net is the notion of hierarchical loggers. Using these loggers it is
possible to selectively control which log statements are output at arbitrary granularity. log4net is designed with two distinct goals in mind: speed and flexibility»
 

ELMAH

A very popular framework. «Stands for Logging Modules and Handlers. An application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications
on a machine, without any need for re-compilation or re-deployment.»
 

NLog

Newer but 3rd popular «A logging platform for .NET with rich log routing and management capabilities. It can help you produce and manage high-quality logs for your application regardless of its size or complexity.»

NuGet

All of the above frameworks are available through NuGet. If you don’t already have NuGet, it is like an App store for Visual Studio application development. If you want a logging framework, or an MVVM framework, simply open the package manager and search.
Results are listed by popularity. Click to install, and the package gets downloaded and integrated into your current project. That means all the dlls are added and registered, and any supporting files are added to your project. It takes all the pain out of
adding supporting packages to your project. This is a must for all developers. No excuses, get it now! 


Return to Top


See Also

  • Troubleshooting Portal
  • See routed events article
    http://code.msdn.microsoft.com/silverlight/WPFSilverlight-Routed-49a16914

 ↑
Return to Top


Community Resources

  • Debugging WPF — WPF Tree Visualizer + Helper Class
  • How to: Use the WPF Tree Visualizer
  • How to: Display WPF Trace Information
  • Trees in WPF
  • Breakpoints
  • Locals Window
  • Threads Window
  • Output Window
  • Exception.InnerException Property
  • Application.DispatcherUnhandledException Event
  • AppDomain.UnhandledException Event
  • Dispatcher.UnhandledException Event
  • Tips on how to debug and learn about WPF
  • WPF performance Suite (in Windows SDK)
  • UI Spy (in Windows SDK)
  • Spy++
  • StyleSnooper
  • Optimizing WPF Application Performance
  • Debugging Tools (.NET Framework)
  • Debugging in Visual Studio
  • Debugging Managed Code
  • Debugging, Tracing, and Profiling 


Return to Top


Data binding:

Since data bindings are evaluated at runtime, and no exceptions are thrown when they fail, a bad binding can sometimes be very hard to track down. These
problems can occur in several different situations, but a common issue is when you try to bind to a property that doesn’t exist, either because you
remembered its name wrong or because you simply misspelled it. Here’s an example:

<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>

The Output window

The first place you will want to look is the Visual Studio Output window. It should be at the bottom of your Visual Studio window, or you can activate it
by using the [Ctrl+Alt+O] shortcut. There will be loads of output from the debugger, but somewhere you should find a line like this, when running the above
example:


System.Windows.Data Error: 40 : BindingExpression path error: ‘NonExistingProperty’ property not found on ‘object’ »Grid’ (Name=’pnlMain’)’.
BindingExpression:Path=NonExistingProperty; DataItem=’Grid’ (Name=’pnlMain’); target element is ‘TextBlock’ (Name=»); target property is ‘Text’ (type
‘String’)

This might seem a bit overwhelming, mainly because no linebreaks are used in this long message, but the important part is this:

‘NonExistingProperty’ property not found on ‘object’ »Grid’ (Name=’pnlMain’)’.

It tells you that you have tried to use a property called «NonExistingProperty» on an object of the type Grid, with the name pnlMain. That’s actually
pretty concise and should help you correct the name of the property or bind to the real object, if that’s the problem.

Adjusting the trace level

The above example was easy to fix, because it was clear to WPF what we were trying to do and why it didn’t work. Consider this next example though:

<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>

I’m trying to bind to the property «Title», but on which object? As stated in the article on data contexts, WPF will use the DataContext property on the
TextBlock here, which may be inherited down the control hierarchy, but in this example, I forgot to assign a data context. This basically means that I’m
trying to get a property on a NULL object. WPF will gather that this might be a perfectly valid binding, but that the object just hasn’t been initialized
yet, and therefore it won’t complain about it. If you run this example and look in the Output window, you won’t see any binding errors.

However, for the cases where this is not the behavior that you’re expecting, there is a way to force WPF into telling you about all the binding problems it
runs into. It can be done by setting the TraceLevel on the PresentationTraceSources object, which can be found in the System.Diagnostics namespace:

<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>

Notice that I have added a reference to the System.Diagnostics namespace in the top, and then used the property on the binding. WPF will now give you loads
of information about this specific binding in the Output window:

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 ''

By reading through the list, you can actually see the entire process that WPF goes through to try to find a proper value for your TextBlock control.
Several times you will see it being unable to find a proper DataContext, and in the end, it uses the default {DependencyProperty.UnsetValue} which
translates into an empty string.

Using the real debugger

The above trick can be great for diagnosing a bad binding, but for some cases, it’s easier and more pleasant to work with the real debugger. Bindings
doesn’t natively support this, since they are being handled deep inside of WPF, but using a Converter, like shown in a previous article, you can actually
jump into this process and step through it. You don’t really need a Converter that does anything useful, you just need a way into the binding process, and
a dummy converter will get you there:

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

In the Code-behind file, we define a DebugDummyConverter. In the Convert() and ConvertBack() methods, we call Debugger.Break(), which has the same effect
as setting a breakpoint in Visual Studio, and then return the value that was given to us untouched.

In the markup, we add a reference to our converter in the window resources and then we use it in our binding. In a real world application, you should
define the converter in a file of its own and then add the reference to it in App.xaml, so that you may use it all over the application without having to
create a new reference to it in each window, but for this example, the above should do just fine.

If you run the example, you will see that the debugger breaks as soon as WPF tries to fetch the value for the title of the window. You can now inspect the
values given to the Convert() method, or even change them before proceeding, using the standard debugging capabilities of Visual Studio.

If the debugger never breaks, it means that the converter is not used. This usually indicates that you have an invalid binding expression, which can be
diagnosed and fixed using the methods described in the start of this article. The dummy-converter trick is only for testing valid binding expressions.

This article has been fully translated into the following languages:

  • Bulgarian

  • Chinese

  • Danish

  • French

  • German

  • Italian

  • Japanese

  • Polish

  • Portuguese

  • Russian

  • Spanish

  • Swedish

  • Vietnamese

Is your preferred language not on the list? Click here to help us translate this article into your language!


Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Windows whistler advanced server
  • Modern flyouts windows 10 не работает
  • Windows sonic или dolby atmos for headphones
  • Аппаратная ошибка веб камеры windows 10
  • Tina turner steamy windows mp3 320