嵌套的Silverlight Datagrid - 行详细信息效果很好,但我想要一个按钮!

时间:2009-08-07 01:53:20

标签: silverlight-3.0 datagrid nested

我正在使用silverlight 3数据网格,在其中,我使用rowdetails(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 datagrid的工作原理,甚至是如何实现rowdetailstemplate的东西。我只是想延迟加载任何细节,直到有意地扩展一行(如树一样)。所有的第三方网格似乎都是这样做的,而微软的网格太紧密了。有没有人知道如何解决这个问题?

谢谢,丹尼斯

5 个答案:

答案 0 :(得分:6)

丹尼斯,

如果您还没有找到答案,我想要相同的行为并通过自定义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&lt;&gt;是我实现的一种扩展方法,用于挖掘可视化树。

您还需要将datagrid的HeadersVisibility属性设置为Row或All

答案 1 :(得分:1)

这是实现你想要做的事情的另一种方式:

在DataGrid中设置一个LoadingRow事件,如下所示:

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

在DataGrid中创建一个模板列,其中包含一个Button,如下所示:

<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存储到按钮Tag元素

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

在Buttons EventHandler(在本例中为ToggleRowDetailsVisibility)中,我们将提取Row以便我们可以切换其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;
            }
        }
    }

你会注意到“CurrentlyExpandedRow”,这是一个类型为DataGridRow的全局变量,我们存储当前展开的行,这允许我们在打开一个新行时关闭该行。

希望这有帮助。

答案 2 :(得分:1)

除了答案之外,这里提供的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); 
    } 
}

答案 3 :(得分:1)

为此:

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

我们可以使用:

HyperlinkButton button = sender as HyperlinkButton;     
DataGridRow Row = DataGridRow.GetRowContainingElement(button)

答案 4 :(得分:0)

我建议您查看datagrid上的RowVisibilityChanged事件,基本上当行可见性更改为“Visible”时,然后加载该行的信息。