WPF Binding, связанные таблицы
От: OldEthereal  
Дата: 13.05.10 17:50
Оценка:
Добрый вечер.

Подскажите, как организовать вывод вместо айди имени из родительской таблицы. Читал все, что нашел похожего, но так ничего и не понял.
Имеем датасет с двумя таблицами, например, employee(id, first_name, last_name, firm_id) и firm(id, firm_name). Есть соответствующий foreign key в таблице employee.
Таблица employee привязана к ListView, в нем GridView и созданы GridViewColumn для каждой колонки. Как в колонке для поля firm_id вывести firm_name?

Датасет не strong typed. Сделать все нужно не в XAML, а в коде. Меня бы удовлетворило даже решение типа Path=Row.firmRow, но не типизированный датасет. Никак не соображу
Re: WPF Binding, связанные таблицы
От: Аноним  
Дата: 14.05.10 13:33
Оценка:
Если кому-то поможет, привожу свое решение. Во-первых, добавил в таблицы DataRelations, форинкей форинкеем, а рилэйшн все равно надо. Но, к сожалению, так и не смог сделать Path вида "Row.Row.GetParentRow(relationName)" и т.д., может и возможно это, не знаю. Поэтому почитал про конвертеры и сделал пока так:

public class ForeignKeyConverter : IValueConverter
{
    private static ForeignKeyConverter instance;
    public static ForeignKeyConverter Instance()
    {
        get
        {
            if (instance == null)
                instance = new ForeignKeyConverter();
            return instance;
        }
    }

    public object Convert(Object value, Type targeType, object parameter, CultureInfo culture)
    {
        // Получаем класс с информацией об отношении
        DataRelation relation = parameter as DataRelation;
        if (relation == null)
            return value;

        // LINQ-запрос, выбирающий значение из родительской таблицы
        var nameQuery =
            from rows in relation.ParentTable.AsEnumerable()
            where rows.Field<int>(relation.ParentColumns[0].ColumnName) == (int)value
            select rows.Field<string>("name");
            
        return nameQuery.FirstOrDefault().ToString();
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Обратное преобразование нам не нужно
        return null;
    }
}


И указываем конвертер для биндинга

colBinding = new Binding();
colBinding.Path = new PropertyPath(column.ColumnName);

DataRelation parentRelation = null;
foreach (DataRelation relation in table.ParentRelations)
{
    if (relation.ChildColumns[0].ColumnName == column.ColumnName)
        parentRelation = relation;
}
if (parentRelation != null && column.DataType == typeof(int))
{
    colBinding.Converter = ForeignKeyConverter.Instance;
    colBinding.ConverterParameter = parentRelation;
}


Кстати, если кто сможет подсказать, как это
foreach (DataRelation relation in table.ParentRelations)
{
    if (relation.ChildColumns[0].ColumnName == column.ColumnName)
        parentRelation = relation;
}

заменить на LINQ, буду бдагодарен.
Re: WPF Binding, связанные таблицы
От: Peter Fleischer Германия www.informtoools.de
Дата: 18.05.10 05:56
Оценка: 3 (1)
"OldEthereal" <12722@users.rsdn.ru> schrieb im Newsbeitrag
news:3806091@news.rsdn.ru...
> Добрый вечер.
>
> Подскажите, как организовать вывод вместо айди имени из родительской
> таблицы. Читал все, что нашел похожего, но так ничего и не понял.
> Имеем датасет с двумя таблицами, например, employee(id, first_name,
> last_name, firm_id) и firm(id, firm_name). Есть соответствующий foreign
> key в таблице employee.
> Таблица employee привязана к ListView, в нем GridView и созданы
> GridViewColumn для каждой колонки. Как в колонке для поля firm_id вывести
> firm_name?
>
> Датасет не strong typed. Сделать все нужно не в XAML, а в коде. Меня бы
> удовлетворило даже решение типа Path=Row.firmRow, но не типизированный
> датасет. Никак не соображу

Самое простое решение "expression column", напр. так:

[XAML]
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" xmlns:my="clr-namespace:WpfApplication1"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase">
<Window.Resources>
<my:ViewModel x:Key="vm" />
<CollectionViewSource Source="{Binding Source={StaticResource vm},
Path=DT}" x:Key="cvs">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="master"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
<DataTemplate x:Key="dt">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding colC}"/>
<TextBox Text="{Binding master, Mode=OneWay}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<StackPanel DataContext="{Binding Source={StaticResource vm}}">
<ListView ItemsSource="{Binding Source={StaticResource cvs}}"
ItemTemplate="{Binding Source={StaticResource dt}}" />
</StackPanel>
</Window>
[/XAML]

ViewModel:

Imports System.Data

Public Class ViewModel

  Private m As New Model

  Public Sub New()
    ' Add relation
    m.DS.Relations.Add(New DataRelation("rel1", 
m.DS.Tables("Master").Columns("ID"), m.DS.Tables("Child").Columns("FK")))
    ' Add expression column
    m.DS.Tables("Child").Columns.Add("master", GetType(String), 
"parent(rel1).colM")
    ' Set Property DT
    DT = m.DS.Tables("Child")
  End Sub

  Public Property DT As DataTable

End Class


Model

Imports System.Data

Public Class Model

  Public Property DS As New DataSet

  Public Sub New()
    ' Generate Master-Demo-records
    DS.Tables.Add(New DataTable("Master"))
    With DS.Tables("Master")
      With .Columns
        With .Add("ID", GetType(Integer))
          .AutoIncrement = True
          .AutoIncrementSeed = 1
          .AutoIncrementStep = 1
        End With
        .Add("colM", GetType(String))
      End With
      For i = 1 To 9
        Dim r As DataRow = .NewRow
        r.Item("colM") = "Master " & i.ToString
        .Rows.Add(r)
      Next
    End With
    ' Generate Child-Demo-records
    DS.Tables.Add(New DataTable("Child"))
    With DS.Tables("Child")
      With .Columns
        With .Add("ID", GetType(Integer))
          .AutoIncrement = True
          .AutoIncrementSeed = 1
          .AutoIncrementStep = 1
        End With
        .Add("FK", GetType(Integer))
        .Add("colC", GetType(String))
      End With
      Dim rnd As New Random
      For i = 1 To 20
        Dim r As DataRow = .NewRow
        r.Item("FK") = rnd.Next(1, 9)
        r.Item("colC") = "Child " & i.ToString
        .Rows.Add(r)
      Next
    End With
  End Sub

End Class


--
Peter
Posted via RSDN NNTP Server 2.1 beta
Re[2]: WPF Binding, связанные таблицы
От: Аноним  
Дата: 13.07.11 11:10
Оценка:
Здравствуйте, Peter Fleischer, Вы писали:


PF>Самое простое решение "expression column", напр. так:


Здаесь уже
Re[3]: WPF Binding, связанные таблицы
От: DroniC  
Дата: 13.07.11 12:16
Оценка:
Здравствуйте, Peter Fleischer, Вы писали:
Самое простое решение "expression column", напр. так:

Извиняюсь за предыдущий пост, я думал от анонима не отправляет и даст форму зарегистрироваться. Можно предыдущий пост удалить.
Так далее по теме, в принципе на данный момент можно просто указать в XAML в DataTemplate например как RelationName/ColumnNameFromChildTable, ListView все отображает на ура, только вот проблема при изменении данных ParentTable, значения в ListView обновляются те которые выбраны из ParentTable, а вот те которые взялись с DataRelation они не обновились. Уже все перепробовал, переискал способы обновления, бесполезно, ничего не помогает.
Надеюсь на Вас.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.