sách gpt4 ăn đã đi

c# - WPF 自定义布局/虚拟化

In lại 作者:太空狗 更新时间:2023-10-29 22:22:55 29 4
mua khóa gpt4 giày nike

这是我试图通过 WPF 实现的目标。 wrappanel 中作为标题和下方按钮的文本 block 。问题是这需要滚动等。我已经使用 ItemsControl 和每个组的绑定(bind)实现了这一点。我有一个 ItemsControl,它有一个堆栈面板作为面板模板,它的项目模板是一个文本 block 和一个包装面板。

它可以工作,但是当项目很多时,在慢速的 intel gma + atom 机器上实例化速度很慢。似乎渲染不是问题,而是视觉树的创建。所以我在这里唯一的赌注是创建一个虚拟化的自定义面板,我猜?

这是我所做的。 http://pastebin.com/u8C7ddP0
上述解决方案在某些机器上速度很慢。

我正在寻找一种在慢速机器上最多需要 100 毫秒才能创建的解决方案。谢谢

gia hạn

 public class PreferenceCheckedConvertor : IMultiValueConverter
{


public object Convert(object[] values, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{

var preference = values[0] as OrderItemPreference;
var items = values[1] as ObservableCollection;

var found = items.FirstOrDefault(item => item.Preference.Id == preference.Preference.Id);
if (found == null)
{
trả về false;
}
trả về giá trị đúng;

}
public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, System.Globalization.CultureInfo culture)
{
thử
{
trả về giá trị null;
}
catch (Exception e)
{
trả về giá trị null;
}
}


}

đóng cửa

public class PreferenceConvertor : IMultiValueConverter
{
public object Convert(object[] values, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
{
var preferences=values[0] as IEnumerable;
var items=values[1] as ObservableCollection;

var newList = new List(preferences.Count());



foreach (var preference in preferences)
{
var curItem = items.FirstOrDefault(item => item.Preference.Id == preference.Id);

if (curItem == null)
{
newList.Add(new OrderItemPreference()
{
Preference = preference
});
}
khác
{
newList.Add(curItem);
}

}

return newList;







}
public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, System.Globalization.CultureInfo culture)
{
thử
{
trả về giá trị null;
}
catch (Exception e)
{
trả về giá trị null;
}
}}

nhập mô tả hình ảnh ở đây

câu trả lời hay nhất

要使 WPF 布局更快,您需要启用虚拟化。在您的代码中:

  1. 删除包装所有控件的 ScrollViewer
  2. 将顶级 ItemsControl Thay thế bằng ListBox:


    ScrollViewer.HorizontalScrollBarVisibility="Disabled" ... >
  3. Sẽ ListBox của ItemsPanel TRONG StackPanel Thay thế bằng VirtualizingStackPanel:


    VirtualizationMode="Recycling"/>

这将为顶级项目启用虚拟化。在我的电脑上,这允许在 1 秒内显示 100,000 个项目。

Để ý:

  1. 虽然您认为瓶颈是 WPF 布局,但您可能错了,因为您还没有分析您的应用程序。因此,虽然这回答了您的问题,但实际上可能无法解决窗口工作缓慢的问题。探查器不仅可以分析您的代码,还可以分析框架代码。他们分析电话、内存等,而不是你的消息来源。它们是提高性能的绝佳工具,也是找到性能问题根源的唯一真正方法。

  2. 为了所有神圣的爱,请阅读 http://sscce.org !如果您不尝试使您的示例简短、自包含和可编译,您将没有足够的声誉来解决所有代码问题。只是为了运行您的示例,我不得不创建自己的 View 模型,摆脱所有不相关的代码,简化绑定(bind),更不用说您自己的各种转换器、控件和绑定(bind)了,这些在任何地方都没有描述。

    <

已更新以支持 .NET 4.0

public static class PixelBasedScrollingBehavior
{
public static bool GetIsEnabled (DependencyObject obj)
{
return (bool)obj.GetValue(IsEnabledProperty);
}

public static void SetIsEnabled (DependencyObject obj, bool value)
{
obj.SetValue(IsEnabledProperty, value);
}

public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(PixelBasedScrollingBehavior),
new UIPropertyMetadata(false, IsEnabledChanged));

private static void IsEnabledChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var isEnabled = (bool)e.NewValue;

if (d is VirtualizingPanel) {
if (TrySetScrollUnit(d, isEnabled))
trở lại;
if (!TrySetIsPixelBased(d, isEnabled))
throw new InvalidOperationException("Failed to set IsPixelBased or ScrollUnit property.");
}
if (d is ItemsControl) {
TrySetScrollUnit(d, isEnabled);
}
}

private static bool TrySetScrollUnit (DependencyObject ctl, bool isEnabled)
{
// .NET 4.5: ctl.SetValue(VirtualizingPanel.ScrollUnitProperty, isEnabled ? ScrollUnit.Pixel : ScrollUnit.Item);

var propScrollUnit = typeof(VirtualizingPanel).GetField("ScrollUnitProperty", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
if (propScrollUnit == null)
trả về false;
var dpScrollUnit = (DependencyProperty)propScrollUnit.GetValue(null);

var assemblyPresentationFramework = typeof(Window).Assembly;
var typeScrollUnit = assemblyPresentationFramework.GetType("System.Windows.Controls.ScrollUnit");
if (typeScrollUnit == null)
trả về false;
var valueScrollUnit = Enum.Parse(typeScrollUnit, isEnabled ? "Pixel" : "Item");

ctl.SetValue(dpScrollUnit, valueScrollUnit);
trả về giá trị đúng;
}

private static bool TrySetIsPixelBased (DependencyObject ctl, bool isEnabled)
{
// .NET 4.0: ctl.IsPixelBased = isEnabled;

var propIsPixelBased = ctl.GetType().GetProperty("IsPixelBased", BindingFlags.NonPublic | BindingFlags.Instance);
if (propIsPixelBased == null)
trả về false;

propIsPixelBased.SetValue(ctl, isEnabled, null);
trả về giá trị đúng;
}
}

需要在 ListBoxVirtualizingStackPanel 上都设置 local:PixelBasedScrollingBehavior.IsEnabled="True",否则滚动将在项目中起作用模式。代码在 .NET 4.0 中编译。如果安装了 .NET 4.5,它将使用新属性。

工作示例:

MainWindow.xaml


xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:So17371439ItemsLayoutBounty"
Title="MainWindow">




















































































MainWindow.xaml.cs

sử dụng Hệ thống;
using System.Collections.ObjectModel;
sử dụng System.Reflection;
using System.Windows;
using System.Windows.Controls;

namespace So17371439ItemsLayoutBounty
{
public partial class MainWindow
{
public ObservableCollection PreferenceGroups { get; private set; }

public MainWindow ()
{
var rnd = new Random();
PreferenceGroups = new ObservableCollection();
for (int i = 0; i < 100000; i++) {
var group = new PreferenceGroup { Name = string.Format("Group {0}", i), SelectionMode = rnd.Next(1, 4) };
int nprefs = rnd.Next(5, 40);
for (int j = 0; j < nprefs; j++)
group.Preferences.Add(new Preference { Name = string.Format("Pref {0}", j), Quantity = rnd.Next(100) });
PreferenceGroups.Add(group);
}
InitializeComponent();
}
}

public class PreferenceGroup
{
public string Name { get; set; }
public int SelectionMode { get; set; }
public ObservableCollection Preferences { get; private set; }

public PreferenceGroup ()
{
Preferences = new ObservableCollection();
}
}

public class Preference
{
public string Name { get; set; }
public string GroupId { get; set; }
public int Quantity { get; set; }
}

public static class PixelBasedScrollingBehavior
{
public static bool GetIsEnabled (DependencyObject obj)
{
return (bool)obj.GetValue(IsEnabledProperty);
}

public static void SetIsEnabled (DependencyObject obj, bool value)
{
obj.SetValue(IsEnabledProperty, value);
}

public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(PixelBasedScrollingBehavior),
new UIPropertyMetadata(false, IsEnabledChanged));

private static void IsEnabledChanged (DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var isEnabled = (bool)e.NewValue;

if (d is VirtualizingPanel) {
if (TrySetScrollUnit(d, isEnabled))
trở lại;
if (!TrySetIsPixelBased(d, isEnabled))
throw new InvalidOperationException("Failed to set IsPixelBased or ScrollUnit property.");
}
if (d is ItemsControl) {
TrySetScrollUnit(d, isEnabled);
}
}

private static bool TrySetScrollUnit (DependencyObject ctl, bool isEnabled)
{
// .NET 4.5: ctl.SetValue(VirtualizingPanel.ScrollUnitProperty, isEnabled ? ScrollUnit.Pixel : ScrollUnit.Item);

var propScrollUnit = typeof(VirtualizingPanel).GetField("ScrollUnitProperty", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
if (propScrollUnit == null)
trả về false;
var dpScrollUnit = (DependencyProperty)propScrollUnit.GetValue(null);

var assemblyPresentationFramework = typeof(Window).Assembly;
var typeScrollUnit = assemblyPresentationFramework.GetType("System.Windows.Controls.ScrollUnit");
if (typeScrollUnit == null)
trả về false;
var valueScrollUnit = Enum.Parse(typeScrollUnit, isEnabled ? "Pixel" : "Item");

ctl.SetValue(dpScrollUnit, valueScrollUnit);
trả về giá trị đúng;
}

private static bool TrySetIsPixelBased (DependencyObject ctl, bool isEnabled)
{
// .NET 4.0: ctl.IsPixelBased = isEnabled;

var propIsPixelBased = ctl.GetType().GetProperty("IsPixelBased", BindingFlags.NonPublic | BindingFlags.Instance);
if (propIsPixelBased == null)
trả về false;

propIsPixelBased.SetValue(ctl, isEnabled, null);
trả về giá trị đúng;
}
}
}

关于c# - WPF 自定义布局/虚拟化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17371439/

29 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress