我正在尝试为ListView
实现一个自定义的GridView
,但是我需要找到一种方法来获取与该GridView
关联的ListView
,因为我需要访问一些ListView
属性(Width
、Items
、Template
...)。
我发现一个老帖子在Get the parent listview from a gridview object上问了同样的问题,但从来没有得到答案……
如果有人有一个想法,我会很高兴:)
编辑:这里有一些来自定制GridView
的基本代码
public class GridViewEx : GridView
{
public ListView Owner {get; set;} // This is what I need to get
public GridViewEx()
{
}
}
EDIT2:我发现了另一种解决方案,而不是mm8提出的解决方案。由于我还需要一个在ListView Scrollviewer Style
中使用的自定义GridViewHeaderRowPresenter
,下面是我想出来的(就目前而言):
public class GridViewHeaderRowPresenterEx : GridViewHeaderRowPresenter
{
private GridViewEx _GridView;
public GridViewHeaderRowPresenterEx()
{
Loaded += OnLoaded;
Unloaded += OnUnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (this.GetVisualParent<ListView>() is ListView lv && lv.View is GridViewEx gridView)
{
_GridView = gridView;
_GridView.Owner = lv;
}
}
private void OnUnLoaded(object sender, RoutedEventArgs e)
{
if (_GridView != null)
_GridView.Owner = null;
}
}
下面是从自定义GridViewHeaderRowPresenter
获取ListView
的扩展方法
public static class DependencyObjectExtensions
{
public static T GetVisualParent<T>(this DependencyObject depObj) where T : DependencyObject
{
if (VisualTreeHelper.GetParent(depObj) is DependencyObject parent)
{
var result = (parent as T) ?? GetVisualParent<T>(parent);
if (result != null)
return result;
}
return null;
}
}
GridViewHeaderRowPresenter
Loaded
事件在将GridView
添加到ListView
时调用,Unloaded
事件在GridView
从ListView
中删除时调用。
与mm8的解决方案相比,我更喜欢这个解决方案,因为它要求(如果我没有弄错的话) ListView
必须有Items
才能工作。
感谢您的建议:)
发布于 2018-06-18 16:26:56
您可以重写PrepareItem
方法并使用ItemsControl.ItemsControlFromItemContainer
方法获取对父ListView
的引用
public class GridViewEx : GridView
{
public ListView Owner { get; set; }
public GridViewEx()
{
}
protected override void PrepareItem(ListViewItem item)
{
base.PrepareItem(item);
Owner = Owner ?? ItemsControl.ItemsControlFromItemContainer(item) as ListView;
}
}
发布于 2018-06-17 23:27:56
您可以将Binding与RelativeSource和AncestorType一起使用,请尝试以下代码:
XAML:
<Grid>
<ListView ItemsSource="{Binding}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="120" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{Binding Age}" />
<GridViewColumn Header="Mail" Width="150" DisplayMemberBinding="{Binding Mail}" />
<GridViewColumn Header="Test">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button
DataContext="{Binding Path=ItemsSource, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}"
Content="Get ListView ItemsSource Count"
Click="Test_Click" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
C#:
class User
{
public string Name { get; set; }
public int Age { get; set; }
public string Mail { get; set; }
}
public MainWindow()
{
InitializeComponent();
DataContext = new List<User>
{
new User() { Name = "John Doe", Age = 42, Mail = "john@doe-family.com" },
new User() { Name = "Jane Doe", Age = 39, Mail = "jane@doe-family.com" },
new User() { Name = "Sammy Doe", Age = 7, Mail = "sammy.doe@gmail.com" }
};
}
private void Test_Click(object sender, RoutedEventArgs e)
{
if (sender is FrameworkElement fe)
if (fe.DataContext is List<User> users)
MessageBox.Show($"ItemsSource items count: {users.Count()}.", "ListView Test");
}
https://stackoverflow.com/questions/50897433
复制相似问题