Программно настроить содержимое в деталях Silverlight DataGrid - PullRequest
1 голос
/ 19 февраля 2010

Мне нужно динамически установить содержимое в шаблоне DataGrid на основе информации во внешнем файле настроек. Этот файл настроек указывает, какие поля данных должны отображаться в DataGrid. Администратор приложения может редактировать настройки, чтобы изменить отображаемые поля. Я не могу жестко закодировать поля для отображения.

Я могу легко добавить столбцы (DataGridTextColumn's) в DataGrid во время выполнения. Я установил привязку к полю в источнике элемента на основе настроек, и это отображается нормально.

Теперь мне нужно отобразить детали, когда пользователь щелкает строку. Я установил RowDetailsTemplate с DataTemplate и добавил Grid (или StackPanel) внутри для форматирования деталей. Если я добавлю к разметке TextBlocks с привязками к полям, он отобразит детали просто отлично.

Но как программно настроить содержимое Grid / StackPanel в шаблоне сведений? Элементы управления Grid / StackPanel равны нулю, если я пытаюсь ссылаться на них по имени при запуске (например, в событии страницы Loaded). Я пытался использовать событие Loaded в Grid / StackPanel, чтобы добавить детали. Этот код запускается и появляется для добавления содержимого в Grid / StackPanel, но на самом деле ничего не появляется, когда я щелкаю строку. Я предполагаю, что проблема в том, что шаблон / Grid уже загружен и игнорирует изменения, которые я делаю.

Вот пример кода, который я использую в обработчике для события Loaded. Даже если я сделаю что-нибудь столь же простое, как эта, панель сведений не появится при нажатии на строку.

<data:DataGrid.RowDetailsTemplate>
    <DataTemplate>
        <Border Background="LightBlue" >
            <StackPanel x:Name="resultsDetailsPanel"
                Orientation="Vertical"
                Loaded="resultsDetailsPanel_Loaded">
            </StackPanel>
        </Border>
    </DataTemplate>
</data:DataGrid.RowDetailsTemplate>



    private void resultsDetailsPanel_Loaded(object sender, RoutedEventArgs e)
    {
        if (_resultsGridLoaded)
            return;

        StackPanel detailsPanel = sender as StackPanel;

        TextBlock fieldNameTextBlock = new TextBlock();
        fieldNameTextBlock.Text = "TESTING";
        detailsPanel.Children.Add(fieldNameTextBlock);

        _resultsGridLoaded = true;
    }

1 Ответ

1 голос
/ 19 февраля 2010

Я на самом деле попробовал ваш код и работает. Две вещи, которые вы должны проверить:

  • Ваша переменная _resultsGridLoaded инициализирована как ложная?
  • Вы установили RowDetailsVisibilityMode = "VisibleWhenSelected" в вашей DataGrid?

ОБНОВЛЕНИЕ: По какой-то причине больше не работает. Но я нашел два способа исправить это:

  1. Удалить логику resultsGridLoaded.
  2. Если вам нужна эта логика, вы можете добавить обработчик для события SelectionChanged в DataGrid, там вы можете установить для переменной _resultsGridLoaded значение false, чтобы новый StackPanel правильно добавил свое содержимое:


    
        
            
                
                
            
        
    


И код позади:

private void resultsPanel_Loaded(object sender, RoutedEventArgs e)
{
    if (_resultsGridLoaded)
        return;

    StackPanel pane = (StackPanel)sender;

    TextBlock newChild = new TextBlock()
    {
        Text = "New text"
    };

    pane.Children.Add(newChild);

    _resultsGridLoaded = true;
}

private void grid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    _resultsGridLoaded = false;
}

Надеюсь, это поможет

...