WPF datagrid и привязка измененных событий строки набора данных

#wpf #datagrid #strongly-typed-dataset

#wpf #сетка данных #строго типизированный-dataset

Вопрос:

Я борюсь с использованием наборов данных с сеткой данных WPF. Привязка и заполнение сетки отлично работают и очень просты…просто создайте dataset datasource и перетащите его в окно. Вуаля! Но когда я пытаюсь прикрепить событие RowChanged к набору данных, я получаю сообщение об ошибке:

С этой командой уже связан открытый DataReader, который необходимо сначала закрыть.

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

Я читал, что я мог бы добавить «MultipleActiveResultSets = true» в свою строку подключения, но такое ощущение, что я неправильно использую функцию SQLServer, чтобы скрыть что-то, что я сделал неправильно.

Вот мой XAML:

 <Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:local="clr-namespace:Test" x:Class="Test.MainWindow"
        Title="MainWindow" Height="350" Width="1141" Loaded="Window_Loaded">
    <Window.Resources>
        <local:SentinelDBDataSet x:Key="sentinelDBDataSet"/>
        <CollectionViewSource x:Key="changeEventViewSource" Source="{Binding ChangeEvent, Source={StaticResource sentinelDBDataSet}}"/>
    </Window.Resources>
    <Grid DataContext="{StaticResource changeEventViewSource}">
        <DataGrid x:Name="changeEventDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" ItemsSource="{Binding}" Margin="0
                  " RowDetailsVisibilityMode="VisibleWhenSelected">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="cameraIDColumn" Binding="{Binding CameraID}" Header="Camera ID" Width="SizeToHeader" IsReadOnly="True"/>
                <!--<DataGridTextColumn x:Name="changeEventIDColumn" Binding="{Binding ChangeEventID}" Header="Change Event ID" IsReadOnly="True" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="backgroundID_RefColumn" Binding="{Binding BackgroundID_Ref}" Header="Background ID Ref" Width="SizeToHeader"/>
                <DataGridTextColumn x:Name="backgroundID_ChangeColumn" Binding="{Binding BackgroundID_Change}" Header="Background ID Change" Width="SizeToHeader"/>-->
                <DataGridTemplateColumn x:Name="timeStampColumn" Header="Time Stamp" Width="SizeToHeader" IsReadOnly="True">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <DatePicker SelectedDate="{Binding TimeStamp, Mode=TwoWay, NotifyOnValidationError=true, ValidatesOnExceptions=true}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTextColumn x:Name="annotationColumn" Binding="{Binding Annotation}" Header="Annotation" Width="SizeToHeader" IsReadOnly="False"/>
                <DataGridCheckBoxColumn x:Name="validatedColumn" Binding="{Binding Validated}" Header="Validated" Width="SizeToHeader" IsReadOnly="True"/>
                <DataGridTextColumn x:Name="confidenceColumn" Binding="{Binding Confidence}" Header="Confidence" Width="SizeToHeader" IsReadOnly="True"/>
                <!--<DataGridCheckBoxColumn x:Name="focusChangedColumn" Binding="{Binding FocusChanged}" Header="Focus Changed" Width="SizeToHeader"/>-->
                <DataGridCheckBoxColumn x:Name="focusDeltaChangedColumn" Binding="{Binding FocusDeltaChanged}" Header="Focus Delta Changed" Width="SizeToHeader" IsReadOnly="True"/>
                <!--<DataGridCheckBoxColumn x:Name="brightnessChangedColumn" Binding="{Binding BrightnessChanged}" Header="Brightness Changed" Width="SizeToHeader"/>-->
                <DataGridCheckBoxColumn x:Name="correlationChangedColumn" Binding="{Binding CorrelationChanged}" Header="Correlation Changed" Width="SizeToHeader" IsReadOnly="True"/>
                <DataGridCheckBoxColumn x:Name="edgeCorrelationChangedColumn" Binding="{Binding EdgeCorrelationChanged}" Header="Edge Correlation Changed" Width="SizeToHeader" IsReadOnly="True"/>
                <DataGridCheckBoxColumn x:Name="edgeDensityChangedColumn" Binding="{Binding EdgeDensityChanged}" Header="Edge Density Changed" Width="SizeToHeader" IsReadOnly="True"/>
            </DataGrid.Columns>
        </DataGrid>

    </Grid>
</Window>
 

И вот мой класс MainWindow:

  public partial class MainWindow : Window
    {
        SentinelDBDataSet dataset;
        SentinelDBDataSetTableAdapters.ChangeEventTableAdapter adapter;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            dataset = ((Test.SentinelDBDataSet)(this.FindResource("sentinelDBDataSet")));

            // Load data into the table ChangeEvent. You can modify this code as needed.            
            adapter = new Test.SentinelDBDataSetTableAdapters.ChangeEventTableAdapter();            
            adapter.Fill(dataset.ChangeEvent);

            System.Windows.Data.CollectionViewSource changeEventViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("changeEventViewSource")));
            changeEventViewSource.View.MoveCurrentToFirst();

            dataset.ChangeEvent.RowChanged  = ChangeEvent_RowChanged;

        }

        void ChangeEvent_RowChanged(object sender, System.Data.DataRowChangeEventArgs e)
        {            
            adapter.Update(dataset.ChangeEvent);            
        }
    }
 

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

Брайан

Комментарии:

1. I'm struggling with using datasets with a WPF datagrid — Совершенно верно. Вы больше не должны использовать datasets в WPF. Они просто прославленные Dictionary<string,object> , которые заставляют вас погружаться в ад нетипизированных вещей, постоянного кастинга и всего, что связано с магическими струнами. Создайте правильную реализацию строго типизированной объектной модели INotifyPropertyChanged , и все ваши проблемы волшебным образом исчезнут.

2. @HighCore = спасибо за ваш совет. Похоже, мне нужно сделать шаг назад и, возможно, рассмотреть новый подход. Я не вкладываю много средств в наборы данных, но они соблазнительны с точки зрения ввода / вывода данных из вашей базы данных без написания большого количества кода. Это «соединительная» часть с элементами управления, которая, кажется, исчезает в сорняках. Что ж, я думаю, мне пора искать «строго типизированную объектную модель» и «INotifyPropertyChanged».