如何解决WPF ListView 绑定到集合 - 找到父扩展器
我编写了一个显示绘图列表的应用程序,作为测试,我编写了一个小应用程序来显示我设想的工作方式。
该应用程序的工作原理:
-
有一个WPF ListView绑定一个ObservableCollection,并使用ICollectionView来显示基于三层分组嵌套的列表视图中的browserItems
-
当应用程序运行时,它会创建多个 browserItems,设置它们的名称和分组等,并在 ListView 中显示这些项目
这一切都很好。
作为测试,该应用程序有一个滑块,它根据滑块编号简单地将 browserItem 的 Active 属性设置为 true - 这会导致它在列表视图中以绿色突出显示,因为 Active 是字体背景的绑定属性.
我希望发生的是当它以绿色突出显示时,例程将自动展开所有扩展器,以便用户无需寻找即可看到突出显示的项目。
有什么办法可以获得浏览器项目的父扩展器吗?
代码可以在这里下载: https://drive.google.com/file/d/1MW-v2gqFtubhnZdKUYGglQLN3S5xnVB4/view?usp=sharing
浏览器项目类:
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ListBoxTest3
{
public partial class browserItem : viewmodelBase
{
/// <summary>
/// browserItem represents a node on the browser treeview structure and relates to either a browser branch or a view / sheet
/// </summary>
//Group one nesting level
private string _l1group;
public string L1group
{
get
{
return _l1group;
}
set
{
_l1group = value;
OnPropertyChanged(nameof(L1group));
}
}
//Group two nesting level
private string _l2group;
public string L2group
{
get
{
return _l2group;
}
set
{
_l2group = value;
OnPropertyChanged(nameof(L2group));
}
}
//Group three nesting level
private string _l3group;
public string L3group
{
get
{
return _l3group;
}
set
{
_l3group = value;
OnPropertyChanged(nameof(L3group));
}
}
//Name
private string _name;
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged(nameof(Name));
}
}
}
//Active or _active = is bound to the active view highlight
private bool _active;
public bool Active
{
get => _active;
set
{
if (value != _active)
{
_active = value;
OnPropertyChanged(nameof(Active));
}
}
}
}
}
MainWindow.Xaml:
<Window x:Class="ListBoxTest3.MainWindow"
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:local="clr-namespace:ListBoxTest3"
mc:Ignorable="d"
Title="MainWindow"
Height="450"
Width="400">
<Grid>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal"
Margin="10">
<TextBlock Text="Filter: " />
<TextBox x:Name="FilterBoxText"
Width="330"
Text="{Binding browserItemFilter,UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal"
Margin="10">
<TextBlock Text="Change Active to number: " />
<Slider x:Name="changeactive"
Width="210"
SmallChange="1"
ValueChanged="Slider_ValueChanged"
IsSnapToTickEnabled="True"
TickFrequency="1"
TickPlacement="Both">
</Slider>
<TextBlock x:Name="displayslider"
Text="0" />
</StackPanel>
</StackPanel>
</StackPanel>
<ListView Name="TreeViewSheets"
Margin="10,10,10"
Height="314"
ItemsSource="{Binding browserItemCollectionView}">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Name}">
<TextBlock.Style>
<Style targettype="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding Active}"
Value="true">
<Setter Property="Background"
Value="YellowGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style targettype="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander>
<Expander.Header>
<TextBlock Text="{Binding Name}"
FontWeight="Bold"
VerticalAlignment="Bottom" />
</Expander.Header>
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
</StackPanel>
</Grid>
</Window>
MainWindow.xaml 背后的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
namespace ListBoxTest3
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
MainWindowviewmodel store
{
get;
set;
}
public MainWindow()
{
InitializeComponent();
store = new MainWindowviewmodel();
store.browser.Add(new browserItem() { Name = "Level 01 Plan",L1group = "Architectural",Active = true,L2group = "Floor Plans",L3group = "1:100" }); ;
store.browser.Add(new browserItem() { Name = "Level 01 Plan",L1group = "Structural",Active = false,L3group = "1:20" });
store.browser.Add(new browserItem() { Name = "Level 02 Plan",L3group = "1:100" });
store.browser.Add(new browserItem() { Name = "Level 02 Plan",L3group = "1:100" });
store.browser.Add(new browserItem() { Name = "Elevation East",L2group = "Elevations",L3group = "1:100" });
store.browser.Add(new browserItem() { Name = "Elevation West",L3group = "1:20" });
store.browser.Add(new browserItem() { Name = "Elevation north",L3group = "1:100" });
store.browser.Add(new browserItem() { Name = "Section A-A",L2group = "Sections",L3group = "1:100" });
store.browser.Add(new browserItem() { Name = "Section B-B",L3group = "1:100" });
store.browser.Add(new browserItem() { Name = "Section C-C",L3group = "1:100" });
store.browser.Add(new browserItem() { Name = "Main Section",L2group = "Main Sections",L3group = "1:100" });
store.browser.Add(new browserItem() { Name = "Level 01 RCP",L2group = "Ceiling Plans",L3group = "1:100" });
TreeViewSheets.DataContext = store;
FilterBoxText.DataContext = store;
//Set slider max value
changeactive.Maximum = store.browser.Count() - 1;
}
private void Slider_ValueChanged(object sender,RoutedPropertyChangedEventArgs<double> e)
{
//When slider is moved,set the item in the list as active
for (int f=0; f < store.browser.Count; f++)
{
if (f == changeactive.Value)
{
store.browser[f].Active = true;
displayslider.Text = f.ToString();
TreeViewSheets.ScrollIntoView(store.browser[f]);
}
else
{
store.browser[f].Active = false;
}
}
}
}
}
MainWindowviewmodel 类,它包含包含浏览器项目的 ObservableCollection。它还具有 MainWindowviewmodel 的构造函数,该构造函数使用 CollectionViewSource 进行分组 - 这会根据 browserItem 类的 L1Group、L2Group 和 L3Group 字段为 Listview 动态创建组扩展器:
class MainWindowviewmodel : viewmodelBase
{
public ICollectionView browserItemCollectionView { get; }
private ObservableCollection<browserItem> _browser = new ObservableCollection<browserItem>();
public ObservableCollection<browserItem> browser
{
get => _browser;
set
{
if (value != _browser)
{
_browser = value;
OnPropertyChanged(nameof(browser));
}
}
}
private string _browserItemFilter = string.Empty;
public string browserItemFilter
{
get
{
return _browserItemFilter;
}
set
{
_browserItemFilter = value;
OnPropertyChanged(nameof(browserItemFilter));
browserItemCollectionView.Refresh();
}
}
public MainWindowviewmodel()
//Constructor
{
browserItemCollectionView = CollectionViewSource.Getdefaultview(_browser);
//Set up filter
browserItemCollectionView.Filter = FilterbrowserItems;
//Set up grouping
browserItemCollectionView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(browserItem.L1group)));
browserItemCollectionView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(browserItem.L2group)));
browserItemCollectionView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(browserItem.L3group)));
}
private bool FilterbrowserItems(object obj)
{
if (obj is browserItem check)
{
return check.Name.Contains(browserItemFilter);
}
return false;
}
}
解决方法
您可以将 </li>
<li class="nav-item"><a class="nav-link" href="{% url 'about' %}">About</a></li>
<li class="nav-item"><a class="nav-link" href="{% url 'all_hobby_products' %}">Book</a></li>
命名,然后通过其名称在组项的模板中查找或使用Expander
遍历可视化树以查找VisualTreeHelper
:
Expander
查找并展开组中的所有 private void Slider_ValueChanged(object sender,RoutedPropertyChangedEventArgs<double> e)
{
//When slider is moved,set the item in the list as active
for (int index = 0; index < store.Browser.Count; index++)
{
BrowserItem browserItem = store.Browser[index];
if (index == e.NewValue)
{
browserItem .Active = true;
displayslider.Text = index.ToString();
TreeViewSheets.ScrollIntoView(browserItem);
if (TryGetExpanderOfItem(browserItem,out Expander expander))
{
expander.Active = true;
}
}
else
{
browserItem.Active = false;
}
}
}
private bool TryGetExpanderOfItem(object browserItem,out Expander expander)
{
expander = null;
CollectionViewGroup groupItem = this.TreeViewSheets.Items.Groups
.OfType<CollectionViewGroup>()
.FirstOrDefault(group => group.Items.Contains(browserItem));
if (groupItem == null)
{
return false;
}
var groupContainer = this.TreeViewSheets.ItemContainerGenerator.ContainerFromItem(groupItem) as Control;
expander = groupContainer?.Template.FindName("GroupExpander",groupContainer) as Expander;
return expander != null;
}
元素
以下版本返回视觉树中从所选组项开始的所有 Expander
元素:
Expander
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。