Вложенный Silverlight Datagrid - Row Details прекрасно работает, но я хочу кнопку! - PullRequest
5 голосов
/ 07 августа 2009

Я использую сетку данных silverlight 3, и внутри нее я вкладываю связанные записи в другой элемент управления, используя детали строк (visibilitymode = visiblewhenselected).

Мне действительно нравится, как это работает, но я бы предпочел, чтобы сетка отображала детали строк при нажатии кнопки "+", подобно тому, как дерево будет расширяться при нажатии на узел.

Я попытался программно определить шаблон с помощью таких ресурсов:

<Grid.Resources>
    <DataTemplate x:Key="EmptyTemplate">
        <StackPanel>
            <!--<TextBlock Text="Empty Template!!!" />-->
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="SongTemplate">
        <StackPanel>
            <AdminControls:ArtistSongControl x:Name="ArtistSongControl" />
        </Stack>
    </DataTemplate>
</Grid.Resources>

И в событии сетки LoadingRowDetails я бы выбрал, какой шаблон установить:

e.Row.DetailsTemplate = (DataTemplate)LayoutRoot.Resources["SongTemplate"];

Этот метод сработал, но я обнаружил, что у меня возникли проблемы со свертыванием шаблона сведений о предыдущих строках, и даже произошел сбой ie8 (не уверен, что это связано).

По сути, мне очень нравится, как работает сетка данных silverlight 3, и даже как реализован материал rowdetailstemplate. Я просто хотел бы отложить загрузку любых деталей, пока строка не будет расширена преднамеренно (как дерево). Все сторонние сетки, кажется, делают это, и Microsoft очень близка. У кого-нибудь есть идеи, как решить эту проблему?

Спасибо, Деннис

Ответы [ 5 ]

6 голосов
/ 09 октября 2009

Денис

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

private void ToggleButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
    ToggleButton button = sender as ToggleButton;
    DataGridRow row = button.GetVisualAncestorOfType<DataGridRow>();

    if (button.IsChecked == true)
    {
        row.DetailsVisibility = Visibility.Visible;

        //Hide any already expanded row. We only want one expanded at a time for simplicity and
        //because it masks a virtualization bug in the datagrid.
        if (_expandedRow != null)
            _expandedRow.DetailsVisibility = Visibility.Collapsed;

        _expandedRow = row;
    }
    else
    {
        row.DetailsVisibility = Visibility.Collapsed;
        _expandedRow = null;
    }
}

Обратите внимание, что GetVisualAncestorOfType <> - это метод расширения, который я реализовал, чтобы копаться в визуальном дереве.

Вам также необходимо установить для свойства HeadersVisibility таблицы данных значение Row или All

.
1 голос
/ 12 марта 2011

Для этого:

DataGridRow row = button.GetVisualAncestorOfType<DataGridRow>(); 

Мы можем использовать как:

HyperlinkButton button = sender as HyperlinkButton;     
DataGridRow Row = DataGridRow.GetRowContainingElement(button)
1 голос
/ 29 декабря 2009

Помимо ответа uxrx, здесь приведен код для поиска предка

public static partial class Extensions 
{ 
    public static T FindAncestor<T>(DependencyObject obj) where T : DependencyObject 
    { 
        while (obj != null) 
        { 
            T o = obj as T; 
            if (o != null)            
                return o; 

            obj = VisualTreeHelper.GetParent(obj); 
        } 
        return null; 
    } 

    public static T FindAncestor<T>(this UIElement obj) where T : UIElement 
    { 
        return FindAncestor<T>((DependencyObject)obj); 
    } 
}
1 голос
/ 05 ноября 2009

вот еще один способ добиться того, что вы пытаетесь сделать:

В DataGrid настройте Событие LoadingRow следующим образом:

<data:DataGrid LoadingRow="ItemsGrid_LoadingRow" .....

В DataGrid создайте столбец шаблона, который будет содержать кнопку, такую ​​как:

<data:DataGridTemplateColumn CellStyle="{StaticResource DataGridCellStyle1}" CanUserReorder="False">
       <data:DataGridTemplateColumn.CellTemplate>
             <DataTemplate>
                    <Button x:Name="ViewButton" Click="ToggleRowDetailsVisibility" Cursor="Hand" Content="View Details" />                                       
             </DataTemplate>
         </data:DataGridTemplateColumn.CellTemplate>
       </data:DataGridTemplateColumn>

В событии LoadingRow найдите кнопку, которая (в данном случае) хранится в первом столбце DataGrid, затем сохраните текущий DataGridRow в элементе тега кнопки

private void ItemsGrid_LoadingRow(object sender, DataGridRowEventArgs e)
    {
        var ViewButton = (Button)ItemsGrid.Columns[0].GetCellContent(e.Row).FindName("ViewButton");
        ViewButton.Tag = e.Row;
    }

В кнопке EventHandler (в данном случае ToggleRowDetailsVisibility) мы извлечем строку, чтобы мы могли переключать ее DetailsVisibility

In the LoadingRow Event locate the button that is (in this case) stored in the first column of the DataGrid, then store the current DataGridRow into the buttons Tag element

private void ToggleRowDetailsVisibility(object sender, RoutedEventArgs e)
    {
        var Button = sender as Button;
        var Row = Button.Tag as DataGridRow;

        if(Row != null)
        {
            if(Row.DetailsVisibility == Visibility.Collapsed)
            {
                Row.DetailsVisibility = Visibility.Visible;

                //Hide any already expanded row. We only want one expanded at a time for simplicity and
                //because it masks a virtualization bug in the datagrid.
                if (CurrentlyExpandedRow != null)
                {
                    CurrentlyExpandedRow.DetailsVisibility = Visibility.Collapsed;
                }

                CurrentlyExpandedRow = Row;
            }
            else
            {
                Row.DetailsVisibility = Visibility.Collapsed;
                CurrentlyExpandedRow = null;
            }
        }
    }

Вы заметите, что «CurrentExpandedRow», это глобальная переменная типа DataGridRow, в которой мы храним текущую развернутую строку, это позволяет нам закрыть эту строку, когда открывается новая.

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

0 голосов
/ 20 октября 2009

Я предлагаю вам взглянуть на событие RowVisibilityChanged в сетке данных, в основном, когда видимость строки меняется на «Видимый», а затем загрузить информацию для строки.

...