Модераторы: gambit, Kefir, Partizan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ListBox и две DataTable связанные Relations 
:(
    Опции темы
Человек01
Дата 10.3.2009, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 87
Регистрация: 20.2.2009
Где: Абакан, респ. Хак асия, Россия

Репутация: 2
Всего: 2



Диспозиция:
Есть ListBox содержащий masterTable (id,name,id_d). detailsTable (id_d,name)
Хочу сделать чтобы каждый Item ListBox-а содержал TextBlock(name) и ComboBox(id_d,name)
то есть реализовать возможность пользователю заполнить содержимое masterTable/id_d используя осмысленные имена detailsTable, а не циферки

Пытаюсь сделать так:

Код

dataSet = new DataSet();  
DataTable masterTable = new DataTable("Master");
DataTable detailsTable = new DataTable("Details"); 
....
//заполнение таблиц
....
dataSet.Tables.Add(masterTable);  
dataSet.Tables.Add(detailsTable);   
dataSet.Relations.Add("megarelation", masterTable.Columns["id_d"], detailsTable.Columns["id_d"], true); 

DataView v = new DataView(dataset.Tables[0]);
((CollectionViewSource)Resources["masterSource"]).Source = v;
DataView v1 = new DataView(dataset.Tables[1]);
((CollectionViewSource)Resources["detailsSource"]).Source = v1;


Код

<Window.Resources>
    <CollectionViewSource x:Key="masterSource"/>
    <CollectionViewSource x:Key="detailsSource"/>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <ListBox Grid.ColumnSpan="2" DataContext="{DynamicResource masterSource}" ItemsSource="{Binding}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <WrapPanel>
                    <TextBlock Text="{Binding name}"></TextBlock>
                    <ComboBox DataContext="{DynamicResource detailsSource}" ItemsSource="{Binding}" DisplayMemberPath="name" ></ComboBox>
                </WrapPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>


Ну и соответственно нечего не получается, вернее получается на одну четвертую. ComboBox содержит значения из detailsTable при выборе одного из них значения во всех ComboBox меняются на выбранное, не говоря о том что нечего не записывается в соответствующую колонку masterTable. А исходя из вышеизложенной организации вообще не понятно зачем было сделано dataSet.Relations.Add("megarelation", masterTable.Columns["id_d"], detailsTable.Columns["id_d"], true); 
Пытался сделать так:
убрать 
Цитата

DataView v1 = new DataView(dataset.Tables[1]);
((CollectionViewSource)Resources["detailsSource"]).Source = v1;

и заменить 
<CollectionViewSource x:Key="detailsSource"/>
на
<CollectionViewSource x:Key="detailsSource" Source="{Binding Source={StaticResource masterSource}, Path=megarelation}" />
но тогда ComboBox вообще пуст...

Вопрос: как сделать так чтобы ComboBox содержал перечень detailsTable  и позволял выбрать значение, апосля помещая в колонку masterTable соответствующий id_d

Что то я окончательно запутался  smile ... помогите пожалуйста распутаться  smile 

PM MAIL ICQ   Вверх
Человек01
Дата 11.3.2009, 06:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 87
Регистрация: 20.2.2009
Где: Абакан, респ. Хак асия, Россия

Репутация: 2
Всего: 2



В общем сделал. Можно сказать наверное через жо... с подвыподвертом...
Пишу сюда, вдруг кому нибудь пригодится.
Первое все это делал применимо к DataGrid, логика с другими Controls при аналогичной задачи, практически не отличается...
Теория:
1. Грузим основную таблицу(в DataTable), единственно добавляем к запросу это вызов интересующего нас поля связанной таблицы.
Т.е. если у нас в основной таблице есть поле id_type и есть связанная  таблица "type" c полями id_type и name, то соответственно запрос будет выглядеть: select ..., maintable.id_type, type.name... from maintable left outer join type on (type.id_type=maintable.id_type)
2. Грузим связанную таблицу(в DataTable)
2.5. Можно поместить а можно не помещать их в DataSet и связать(я просто поместил)
3. Создаем DataGrid и привязываем к нему основную таблицу datagrid1.ItemsSource = dataset.Tables[0].DefaultView;
4. Создаем CollectionViewSource и привязываем к нему вторую таблицу 
((CollectionViewSource)Resources["typedoc"]).Source = dataset.Tables[1].DefaultView;
5. создаем для столбца DataGridTemplateColumn и реализуем два поведения столбца первое отображение данных второе редактирование данных. Для DataGrid - это делается через DataGridTemplateColumn.CellTemplate и DataGridTemplateColumn.CellEditingTemplate, соответственно.
Для отображения, реализуем отображение текущего сотояния таблицы. А вот для редактирования создаем ComboBox с источником данных из второй таблицы, так же для ComboBox реализуем события загрузки(для установления текущего значения) и изменения выбора(для установления выбранного в основную таблицу)
6. И всё.
Теперь практика:
Код

...
<Windows.Resources>
     ...
     <CollectionViewSource x:Key="typedoc"/>
        <wpf:DataGridTemplateColumn x:Key="columntype">
            <wpf:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <!--- <TextBlock Text="{Binding Path=id_typedocument, Converter={StaticResource convertttt}, ConverterParameter=name}"></TextBlock> -->                    
                    <TextBlock Text="{Binding name}"></TextBlock>
                </DataTemplate>
            </wpf:DataGridTemplateColumn.CellTemplate>            
            <wpf:DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox DataContext="{DynamicResource typedoc}" ItemsSource="{Binding}"
                              SelectionChanged="ComboBox_SelectionChanged" Loaded="ComboBox_Loaded">
                        <ComboBox.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding name}"></TextBlock>
                            </DataTemplate>
                        </ComboBox.ItemTemplate>
                    </ComboBox>
                </DataTemplate>
            </wpf:DataGridTemplateColumn.CellEditingTemplate>
        </wpf:DataGridTemplateColumn>
        ...
   </Window.Resources>
<Grid>
<wpf:DataGrid Name="datagrid1"/>
....


Код

private void init()
{
        ...
        bd.MySqlDataAdapter(sql).Fill(datatable);//заполнение основной таблицы
        bd.MySqlDataAdapter(sqltype).Fill(datatabletypedoc);//заполнение связанной таблицы
        dataset.Tables.Add(datatable);
        dataset.Tables.Add(datatabletypedoc);
        ((CollectionViewSource)Resources["detailsSource"]).Source = dataset.Tables[1].DefaultView; 
        datagrid1.ItemsSource = dataset.Tables[0].DefaultView;
        datagrid1.Columns[3] = (DataGridTemplateColumn)this.Resources["columntype"];
}

private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    if (((ComboBox)sender).Items.Count > 0)
    {
        ((DataRowView)datagrid1.SelectedItem).Row["id_type"] = ((DataRowView)((ComboBox)sender).SelectedItem).Row["id_type"];
        ((DataRowView)datagrid1.SelectedItem).Row["name"] = ((DataRowView)((ComboBox)sender).SelectedItem).Row["name"];
    }            
}

private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{//тут устанавливаем в ComboBox текущее значение основной таблицы, в качестве выбранного значения
    ComboBox cb = (ComboBox)sender;
    int id_t = (int)((DataRowView)datagrid1.SelectedItem).Row["id_type"];
    foreach (DataRowView r in cb.Items)
        if ((int)r.Row[0] == id_t)
        {
            cb.SelectedItem = r;
            break;
        }            
}


Ну собственно и всё, вот такой вот извраще.. интересный вариант решения вопроса.  smile 
Надеюсь кому нибудь пригодится  smile 
Пользуемся и говорим Человеку спасибо  smile 
P.S.: Тему не закрываю, может кто нить знает как это всё сделать правильно и изящно, что ли.


Это сообщение отредактировал(а) Человек01 - 11.3.2009, 06:52
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | WPF и Silverlight | Следующая тема »


 




[ Время генерации скрипта: 0.1796 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.