Привязка таблиц данных к сетям данных в WPF Tabcontrol - PullRequest
1 голос
/ 28 мая 2019

У меня есть wpf TabControl и ListBox. Если я щелкну по одному из элементов в ListBox, я хочу получить данные из определенной таблицы на SQL Server, добавлю новую вкладку в TabControl и выведу данные на DataGrid на этой новой вкладке. Пока у меня есть это:

XAML для TabControl и ListBox:

 <Grid>
    <ListBox x:Name="lb"  ItemsSource="{Binding Alltables}" MouseDoubleClick="opendata"/>

    <TabControl x:Name="tabControl"  ItemsSource="{Binding SelectedTables}">
        <TabControl.ContentTemplate >
            <DataTemplate >
                <Grid>
                    <DataGrid x:Name="dataGrid" AutoGenerateColumns="True" ItemsSource="{Binding Tablecontent}"/>                  
                </Grid>
            </DataTemplate>
        </TabControl.ContentTemplate>
    </TabControl>
</Grid>

Моя ViewModel:

   public class MainViewModel : INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string name)
        {

            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }

        }

        private ObservableCollection<String> selectedtables;
    public ObservableCollection<String> SelectedTables
    {
        get { return selectedtables; }
        set
        {
            if (selectedtables != value)
            {

                selectedtables = value;
                OnPropertyChanged("SelectedTables");
            }
        }
    }

    private ObservableCollection<DataTable> tablecontent;
    public ObservableCollection<DataTable> Tablecontent
    {
        get { return tablecontent; }
        set
        {
            if (tablecontent != value)
            {
                tablecontent = value;
                OnPropertyChanged("Tablecontent");
            }
        }
    }

}

Событие щелчка для ListBox:

   private void opendata(object sender, MouseButtonEventArgs e)
    {
//...
 //Some preparations before querying the data etc.
//...

   DataTable mydata = new DataTable();

        using (connection = new SqlConnection(connectionString))
        {
            SqlCommand command = new SqlCommand(queryString, connection);
            command.Connection.Open();
            SqlDataReader reader = command.ExecuteReader();
            mydata.Load(reader);
        }  

        string tabletoload = lb.SelectedItem.ToString();

        myview2.SelectedTables.Add(tabletoload); //myview2 is the instance of my ViewModel

        myview2.Tablecontent.Add(mydata); //myview2 is the instance of my ViewModel
    }
}

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

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

1 Ответ

1 голос
/ 28 мая 2019

SelectedTables должен вернуть IEnumerable<T>, где тип T определяет имя и DataTable для текущей вкладки:

public class TabViewModel
{
    public string Header { get; set; }
    public DataTable Tablecontent { get; set; }
}

public class MainViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }

    private ObservableCollection<TabViewModel> selectedtables;
    public ObservableCollection<TabViewModel> SelectedTables
    {
        get { return selectedtables; }
        set
        {
            if (selectedtables != value)
            {

                selectedtables = value;
                OnPropertyChanged("SelectedTables");
            }
        }
    }
}

Затем необходимо добавитьновый T (названный TabViewModel в приведенном выше примере кода) для MainViewModel в вашем opendata методе:

string tabletoload = lb.SelectedItem.ToString();
myview2.SelectedTables.Add(new TabViewModel() { Header = tabletoload, Tablecontent = mydata });

... и определение ItemTemplate для TabControl в представлении для отображения заголовка:

<TabControl x:Name="tabControl"  ItemsSource="{Binding SelectedTables}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Header}" />
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate >
        <DataTemplate >
            <Grid>
                <DataGrid x:Name="dataGrid" AutoGenerateColumns="True" ItemsSource="{Binding Tablecontent}"/>
            </Grid>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>
...