Find DataGrid for DataGridColumn
How can I get the DataGrid
for a given DataGridColumn
. I've created an attached property in a subclass of DataGrid
that applies to DataGridColumn
(which I've not subclassed). It gives me the DataGridColumn
on which I apply the attached property, but how do I get the DataGrid
reference itself? I need both.
Edit:
What I'm more interested in, is how in the event handler for an attached property does one get the DependencyObject
instance that 开发者_如何转开发is actually hosting the attached property. That is, the DataGrid
instead of the DataGridColumn
that the property is attached too.
<my:MvvmDataGrid x:Name="_dataGrid" ... >
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn my:MvvmDataGrid.SingleClickEdit="true" .../>
</sdk:DataGrid.Columns>
</my:MvvmDataGrid>
I then have a static handler OnSingleClickEditPropertyChanged
which is registered as the PropertyChangedCallback
on the SingleClickEditProperty
attached property's metadata.
When that property invokes (id est the property was changed on the column), I am given a the DataGridTextColumn
, when I need the MvvmDataGrid
instance.
I think you can use this
Using this code you can found ancestor of the DataGridColumn - your DataGrid in visual tree. This code implemented as static function but you can change it to extension method with more "speaking" name like FindAncestor:
public static class UIElementExtensions
{
public static T FindAncestor<T>(this UIElement control) where T: UIElement
{
UIElement p = VisualTreeHelper.GetParent(control) as UIElement;
if (p != null)
{
if (p is T)
return p as T;
else
return p.FindAncestor<T>();
}
return null;
}
}
and use it:
DataGrid p = dataGridColumn.FindAncestor< DataGrid >();
If you need to get your DataGrid from XAML try to use binding from this article.
Good luck.
UPDATE:
I understand what is the matter. The next answer won't be so easy, but it's silverlight :) So, why you cann't find DataGrid from DataGridColumn using VisualTreeHelper? Because, DataGridColumn doesn't exist in Visual Tree. DataGridColumn inherits from DependencyObject, not UIElement. Forget about VisualTree, and new idea will be like this: we add addition attached property to DataGridColumn - named Owner, and bound DataGrid to this property. But, DataGridColumn is DependencyObject and any bindings by ElementName don't work in silverlight 4. We can bind only to StaticResource. So, do it. 1) Owner attached property for DataGridColumn:
public class DataGridHelper
{
public static readonly DependencyProperty OwnerProperty = DependencyProperty.RegisterAttached(
"Owner",
typeof(DataGrid),
typeof(DataGridHelper),
null));
public static void SetOwner(DependencyObject obj, DataGrid tabStop)
{
obj.SetValue(OwnerProperty, tabStop);
}
public static DataGrid GetOwner(DependencyObject obj)
{
return (DataGrid)obj.GetValue(OwnerProperty);
}
}
2) DataGrid Xaml (for instance):
<Controls:DataGrid x:Name="dg" ItemsSource="{Binding}">
<Controls:DataGrid.Columns>
<Controls:DataGridTextColumn h:DataGridHelper.Owner="[BINDING]"/>
</Controls:DataGrid.Columns>
</Controls:DataGrid>
3) DataGrid Container - keeper of DataGrid instance in StaticResource:
public class DataGridContainer : DependencyObject
{
public static readonly DependencyProperty ItemProperty =
DependencyProperty.Register(
"Item", typeof(DataGrid),
typeof(DataGridContainer), null
);
public DataGrid Item
{
get { return (DataGrid)GetValue(ItemProperty); }
set { SetValue(ItemProperty, value); }
}
}
4) Add to Resources of your view instance of DataGridContainer and bind DataGrid instance to Item property:
<c:DataGridContainer x:Key="ownerContainer" Item="{Binding ElementName=dg}"/>
Here, binding by ElementName will be worked.
5) Last step, we bind our DataGrid to attached property Owner (see p.2 and add next code to [BINDING] section):
{Binding Source={StaticResource ownerContainer}, Path=Item}
That's all. In code, if we have reference to DataGridColumn we can get owned DataGrid:
DataGrid owner = (DataGrid)dataGridColumn.GetValue(DataGridHelper.OwnerProperty);**
Hope this principle will help you.
精彩评论