views:

805

answers:

2

I have the following tables:

Company {CompanyID, CompanyName}
Deal {CompanyID, Value}

And I have a listbox:

<ListBox Name="Deals"
         Height="100" Width="420" Margin="0,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"
         Visibility="Visible" IsSynchronizedWithCurrentItem="True"
         ItemsSource="{Binding}" SelectionChanged="Deals_SelectionChanged">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding companyRowByBuyFromCompanyFK.CompanyName}" FontWeight="Bold"  />
                <TextBlock Text=" -> TGS -> " />
                <TextBlock Text="{Binding BuyFrom}" FontWeight="Bold" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

As you can see, I want to display the CompanyName rather then the ID which is a foreign Key. The relation "companyRowByBuyFromCompanyFK" exists, as in Deals_SelectionChanged I can access companyRowByBuyFromCompanyFK property of the Deals row, and I also can access the CompanyName propert of that row.

Is the reason why this is not working because XAML binding uses the [] indexer? Rather than properties on the CompanyRows in my DataTable?

At the moment im getting values such as

  • -> TGS -> 3
  • -> TGS -> 4

Edit Binding Error Update

System.Windows.Data Error: 39 : BindingExpression path error: 'companyRowByBuyFromCompanyFK' property not found on 'object' ''DataRowView' (HashCode=30295189)'. BindingExpression:Path=companyRowByBuyFromCompanyFK.CompanyName; DataItem='DataRowView' (HashCode=30295189); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

Looks like its not converting the DataRowView item into a SuppliersRow

What would be the best way to accomplish this?

  1. Make a converter to convert foreign keys using Table being referenced as custom parameter.

  2. Create Table View for each table? This would be long winded as I have quite a large number of tables that have foreign keys.

+1  A: 

How about setting a multibinding in the datatemplate that converts the row (the datasource from the listitem), together with a hierarchical binding (that passes the reference to the other table from the parent control) and the name of the field in the other table to search for the id within?

<UserControl x:Class="local:MyUserControl">
    <ListBox ItemsSource="{Binding Items}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Label>
                    <Label.Content>
                        <MultiBinding Converter="{StaticResource myConverter}">
                            <Binding Path="OtherId" />
                            <Binding
                                RelativeSource="RelativeSource FindAncestor,
                                    AncestorType={x:Type local:MyUserControl}}}"
                                Path="OtherTable" />
                        </MultiBinding>
                    </Label.Content>
                </Label>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</UserControl>

In the converter:

public object Convert(object[] values, Type targetType, object parameter,
    System.Globalization.CultureInfo culture)
{
    // TODO: Input type checks

    // TODO: Castings, find key in other table, return relevant field
    return (values[1] as IDictionary<String, String>)[values[0] as String];
}
Danny Varod
Sounds like a good, would it be possible to provide a simple example of any 2 tables.
LnDCobra
+1  A: 

Somebody kill me.... thanks for pointing out the output window I always forget about that! :(

I found the solution by looking at the output window which was the following

System.Windows.Data Error: 39 : BindingExpression path error: 'companyRowByBuyFromCompanyFK' property not found on 'object' ''DataRowView

I figured out that the DataTemplate binding was binding to the SelectedItem of the DataTemplate which is a DataRowView and not the actual strong typed data. Luckily the DataRowView class has a Row property pointing to the DataRow (which is the supplierRow) class therefore I could bind from there as normal. Fix was in the followign line.

<TextBlock Text="{Binding companyRowByBuyFromCompanyFK.CompanyName}" FontWeight="Bold"  />

Changing this to the following worked as I expected it to.

<TextBlock Text="{Binding Row.companyRowByBuyFromCompanyFK.CompanyName}" FontWeight="Bold"  />
LnDCobra