我的GridView
有RowDetail
。我希望每次用户点击行从数据库中获取一些细节时,我都会使用Telerik GridView
。以正常方式,这是不可能的,或者至少我不知道如何,因为RowDetail
上下文直接绑定到网格DataContext
,我想要的不仅仅是GridRow包含它。我发现也许我可以通过命名UserControl
将RowDetailTemplate DataContext设置为UserControl
,以便我可以将RowDetail引用到其他模型。
我的代码是这样的
<UserControl
x:Name="mainPageView"
x:Class="Project.Client.TestView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<DataTemplate x:Key="ContactRowDetailTemplate" >
<Grid Background="Transparent"
DataContext="{Binding DataContext.ContactStatModel,
ElementName=mainPageView,Mode=OneTime}">
<Grid.RowDefinitions>
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="Sent SMS Count" Grid.Column="0" Grid.Row="0" />
<TextBlock Text=":" Grid.Column="1" Grid.Row="0" />
<TextBlock Text="{Binding SMSCount}" Grid.Column="2" Grid.Row="0" />
</Grid>
</DataTemplate>
</UserControl.Resources>
<telerik:RadGridView
x:Name="gridView"
AutoGenerateColumns="False" Height="Auto" Grid.Row="3"
ItemsSource="{Binding VOutboxList, Mode=TwoWay}"
SelectedItem="{Binding VOutboxModel, Mode=TwoWay}"
RowDetailsTemplate="{StaticResource ContactRowDetailTemplate}"
LoadingRowDetails="gridView_LoadingRowDetails">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn UniqueName="FirstName" Header="First Name" Width="150" />
<telerik:GridViewDataColumn UniqueName="LastName" Header="Last Name" Width="150" />
</telerik:RadGridView.Columns>
</telerik:RadGridView>
</UserControl>
但是这次我得到了这个例外
{Error: System.Exception: BindingExpression_CannotFindElementName}
任何建议都会有所帮助。 最诚挚的问候。
答案 0 :(得分:3)
原因是WPF和Silverlights DataGrid列位于逻辑树之外,因此无法使用使用ElementName指定的绑定源,这在引用ViewModel属性(例如DataGrid模板列中的命令)时很常见。有关此问题的详细信息,请参阅:http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its-columns.aspx
下面的课程就像栏目和周围世界之间的粘合剂一样。它是为Silverlight的内置DataGrid编写的,但应该足够容易使其适应Telerik Grid。它可以像这样使用:
<DataTemplate x:Key="ContactRowDetailTemplate" >
<Grid Background="Transparent"
DataContext="{Binding ParentDataGrid.DataContext.ContactStatModel,
ElementName=shim,Mode=OneTime}">
<Shims:DataGridShim x:Name="shim"/>
<Grid.RowDefinitions>
<RowDefinition Height="28" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="Sent SMS Count" Grid.Column="0" Grid.Row="0" />
<TextBlock Text=":" Grid.Column="1" Grid.Row="0" />
<TextBlock Text="{Binding SMSCount}" Grid.Column="2" Grid.Row="0" />
</Grid>
</DataTemplate>
public class DataGridShim : FrameworkElement
{
/// <summary>
/// Initializes a new instance of the <see cref="DataGridShim"/> class.
/// prepares the ParentDataGrid property for consumption by sibling elements in the DataTemplate
/// </summary>
public DataGridShim()
{
Loaded += (s, re) =>
{
ParentDataGrid = GetContainingDataGrid(this);
};
}
/// <summary>
/// Gets or sets the parent data grid.
/// </summary>
/// <value>
/// The parent data grid.
/// </value>
public DataGrid ParentDataGrid { get; protected set; }
/// <summary>
/// Walks the Visual Tree until the DataGrid parent is found and returns it
/// </summary>
/// <param name="value">The value.</param>
/// <returns>The containing datagrid</returns>
private static DataGrid GetContainingDataGrid(DependencyObject value)
{
if (value != null)
{
DependencyObject parent = VisualTreeHelper.GetParent(value);
if (parent != null)
{
var grid = parent as DataGrid;
if (grid != null)
return grid;
return GetContainingDataGrid(parent);
}
return null;
}
return null;
}
}
答案 1 :(得分:3)
我甚至简化了已接受的解决方案。它使用来自DataTemplates的技巧,可以引用静态资源。在静态资源中,您可以在绑定中使用ElementName。
创建一个新控件:
public class ElementProxy : DependencyObject
{
public DependencyObject Element
{
get { return (DependencyObject)GetValue(ElementProperty); }
set { SetValue(ElementProperty, value); }
}
public static readonly DependencyProperty ElementProperty =
DependencyProperty.Register("Element", typeof(DependencyObject), typeof(ElementProxy), new PropertyMetadata(null));
}
将它放入DataGrid或其父控件的静态资源中,并通过StaticResource引用它:
<UserControl.Resources>
<helpers:ElementProxy Element={Binding ElementName=mainPageView} x:Key="Proxy" />
</UserControl.Resources>
(在列模板中:)
<DataTemplate>
<Grid DataContext={Binding Element.DataContext,Source={StaticResource Proxy}} />
</DataTemplate>