Silverlight 4 - привязка ComboBox в DataGrid к свойству класса клиентского контракта WCF - PullRequest
0 голосов
/ 26 декабря 2011

У меня есть сценарий, который, кажется, не рассматривается ни в одном из других подобных вопросов (большинство из которых в любом случае остаются без ответа).

Вот так:

У меня есть следующие пунктыработать с:

1) Службой WCF, которая возвращает очень сложный контракт данных с более чем 100 свойствами.Я не хочу создавать ViewModel этого объекта, так как не хочу поддерживать более 100 свойств , если это не является абсолютно необходимым .

2) У меня есть Silverlight UserControl, который имеет этоконтракт данных, определенный как Ресурс:

<UserControl.Resources>
    <DieEstimateService:DieEstimateContract x:Key="Die" />
</UserControl.Resources>

3) У меня есть сетка данных, которая привязывается к коллекции Die, называемой Die.DieMetalforming.Эта коллекция представляет собой массив объектов DieMetalformingContract.Из этой коллекции можно отобразить два столбца: свойства DiePunchFunctionDescription и DiePunchConstructionDescription.DiePunchFunctionDescription имеет соответствующие ключевые свойства, называемые DiePunchFunctionUID, и аналогично, DiePunchConstructionDescription имеет ключевое свойство, называемое DiePunchConstructionUID.Когда сетка находится в режиме отображения, она использует TextBlocks для отображения полей DiePunchFunctionDescription и DiePunchConstructionDescription.DataGrid привязан к массиву Die.DieMetalforming с помощью следующего кода:

dgDieMetalforming.ItemsSource = Die.DieMetalformings;

4) Когда сетка находится в режиме редактирования, для столбцов DiePunchFunction и DiePunchConstruction имеются комбинированные списки, оба из которых предназначены длябыть привязанным к коллекциям метаданных объекта Die.Эти коллекции называются DiePunchFunctionFields и DiePunchConstructionFields.Обе коллекции являются массивами объектов StandardCostFieldContract (они просто содержат разные данные в зависимости от типа поля).StandardCostFieldContract имеет свойство отображения «FieldDescription» и ключевое свойство «StandardCostFieldUID».

5) Наконец, сетка данных содержит третий столбец свойства «Свойство» элемента DieMetalformingContract.В обычном режиме это TextBlock, а в режиме редактирования это TextBox.Это свойство работает как предназначено для двусторонней привязки данных.

Сетка данных правильно привязывается к источнику данных, о чем свидетельствуют правильные функциональные возможности TextBlocks и TextBox поля количества.Однако я не могу заставить комбо-боксы загружать свои данные из массивов DiePunchFunctions или DiePunchConstructions.Я подготовил дюжину статей на эту тему и перепробовал каждую перестановку связывания ItemSources, которую смог найти, но, похоже, ничего не работает.Вот мое определение таблицы данных:

    <sdk:DataGrid AutoGenerateColumns="False" Height="167" HorizontalAlignment="Stretch" Margin="6,255,6,0" 
                  Name="dgDieMetalforming" VerticalAlignment="Top" Width="Auto" Grid.ColumnSpan="4" 
                  SelectionMode="Single" TabNavigation="Local">
    <sdk:DataGrid.Columns>
        <sdk:DataGridTemplateColumn CanUserReorder="False" CanUserResize="False" 
            CanUserSort="False" Header="Punch/Die Function" Width="Auto" >
            <sdk:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding DiePunchFunctionDescription}" Margin="4" />
                </DataTemplate>
            </sdk:DataGridTemplateColumn.CellTemplate>
            <sdk:DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox Name="ddlDiePunchFunction" ItemsSource="{Binding 
                     Path=Die.DiePunchFunctionFields, Mode=OneWay}" 
                     SelectedItem="{Binding Path=DiePunchFunctionUID, Mode=TwoWay}" 
                     DisplayMemberPath="FieldDescription" 
                     SelectedValuePath="StandardCostFieldUID" />
                </DataTemplate>
            </sdk:DataGridTemplateColumn.CellEditingTemplate>
        </sdk:DataGridTemplateColumn>
        <sdk:DataGridTemplateColumn CanUserReorder="False" CanUserResize="False" 
            CanUserSort="False" Header="Punch/Die Construction" Width="Auto" >
            <sdk:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding DiePunchConstructionDescription}" Margin="4" />
                </DataTemplate>
            </sdk:DataGridTemplateColumn.CellTemplate>
            <sdk:DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox Name="ddlDiePunchFunction" ItemsSource="{Binding 
                     Path=Die.DiePunchConstructionFields, Mode=OneWay}" 
                     SelectedItem="{Binding Path=DiePunchConstructionUID, Mode=TwoWay}" 
                     DisplayMemberPath="FieldDescription" 
                     SelectedValuePath="StandardCostFieldUID" />
                </DataTemplate>
            </sdk:DataGridTemplateColumn.CellEditingTemplate>
        </sdk:DataGridTemplateColumn>
        <sdk:DataGridTemplateColumn CanUserReorder="False" CanUserResize="False" 
             CanUserSort="False" Header="Quantity" Width="Auto" >
            <sdk:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Quantity}" Margin="4" />
                </DataTemplate>
            </sdk:DataGridTemplateColumn.CellTemplate>
            <sdk:DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <TextBox Name="txtQuantity" Text="{Binding Quantity, Mode=TwoWay}" />
                </DataTemplate>
            </sdk:DataGridTemplateColumn.CellEditingTemplate>
        </sdk:DataGridTemplateColumn>
    </sdk:DataGrid.Columns>
</sdk:DataGrid>

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

1 Ответ

1 голос
/ 26 декабря 2011

Я наконец сказал «ВИНТ» для привязки данных и пошел с событиями codebehind, чтобы связать списки. Новая сетка выглядит следующим образом (я добавил некоторые вспомогательные функции с момента публикации вопроса).

    <sdk:DataGrid AutoGenerateColumns="False" Height="167" HorizontalAlignment="Stretch" Margin="6,255,6,0" 
                  Name="dgDieMetalforming" VerticalAlignment="Top" Width="Auto" Grid.ColumnSpan="4" 
                  SelectionMode="Single" TabNavigation="Local">
        <sdk:DataGrid.Columns>
            <sdk:DataGridTemplateColumn CanUserReorder="False" CanUserResize="False" 
                                        CanUserSort="False" Header="Punch/Die Function" Width="Auto" >
                <sdk:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding DiePunchFunctionDescription}" Margin="4" />
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellTemplate>
                <sdk:DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox Name="ddlDiePunchFunction" 
                                  SelectionChanged="ddlDiePunchFunction_SelectionChanged" 
                                  Loaded="ddlDiePunchFunction_Loaded" 
                                  SelectedItem="{Binding Path=DiePunchFunctionUID, Mode=TwoWay}" 
                                  DisplayMemberPath="FieldDescription" 
                                  SelectedValuePath="StandardCostFieldUID" />
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellEditingTemplate>
            </sdk:DataGridTemplateColumn>
            <sdk:DataGridTemplateColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False" 
                                        Header="Punch/Die Construction" Width="Auto" >
                <sdk:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding DiePunchConstructionDescription}" Margin="4" />
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellTemplate>
                <sdk:DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox Name="ddlDiePunchConstruction" 
                                  SelectionChanged="ddlDiePunchConstruction_SelectionChanged" 
                                  Loaded="ddlDiePunchFunction_Loaded" 
                                  SelectedItem="{Binding Path=DiePunchConstructionUID, Mode=TwoWay}" 
                                  DisplayMemberPath="FieldDescription" 
                                  SelectedValuePath="StandardCostFieldUID" />
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellEditingTemplate>
            </sdk:DataGridTemplateColumn>
            <sdk:DataGridTemplateColumn CanUserReorder="False" CanUserResize="False" CanUserSort="False" 
                                        Header="Quantity" Width="Auto" >
                <sdk:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Quantity}" Margin="4" />
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellTemplate>
                <sdk:DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <TextBox Name="txtQuantity" Text="{Binding Quantity, Mode=TwoWay}" />
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellEditingTemplate>
            </sdk:DataGridTemplateColumn>
            <sdk:DataGridTemplateColumn CanUserReorder="false" CanUserResize="False" CanUserSort="False" 
                                        Header="" Width="Auto">
                <sdk:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Button Name="btnDelete" Click="btnDelete_Click">
                            <TextBlock>delete</TextBlock></Button>
                    </DataTemplate>
                </sdk:DataGridTemplateColumn.CellTemplate>
            </sdk:DataGridTemplateColumn>
        </sdk:DataGrid.Columns>
    </sdk:DataGrid>

Кодовая часть выглядит следующим образом.

private void ddlDiePunchFunction_Loaded(object sender, RoutedEventArgs e)
{
    var src = sender as ComboBox;
    if (src.IsNotNull())
    {
        var data = src.DataContext as DieMetalformingContract;
        switch (src.Name)
        {
            case "ddlDiePunchFunction":
                src.ItemsSource = Die.DiePunchFunctionFields;
                src.SelectedValue = data.DiePunchFunctionUID;
                break;
            case "ddlDiePunchConstruction":
                src.ItemsSource = Die.DiePunchConstructionFields;
                src.SelectedValue = data.DiePunchConstructionUID;
                break;
        }
    }
}

private void ddlDiePunchFunction_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var src = sender as ComboBox;
    if (src.IsNotNull())
    {
        var data = src.DataContext as DieMetalformingContract;
        data.DiePunchFunctionUID = src.SelectedValue.ToNullableGuid() ?? Guid.Empty;
        data.DiePunchFunctionDescription = (from x in Die.DiePunchFunctionFields
                                            where x.StandardCostFieldUID == data.DiePunchFunctionUID
                                            select x.FieldDescription).FirstOrDefault();
    }
}

private void ddlDiePunchConstruction_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var src = sender as ComboBox;
    if (src.IsNotNull())
    {
        var data = src.DataContext as DieMetalformingContract;
        data.DiePunchConstructionUID = src.SelectedValue.ToNullableGuid() ?? Guid.Empty;
        data.DiePunchConstructionDescription = (from x in Die.DiePunchConstructionFields
                                            where x.StandardCostFieldUID == data.DiePunchConstructionUID
                                            select x.FieldDescription).FirstOrDefault();
    }
}

Спасибо всем, кто прочитал это.

...