小编Dan*_*zen的帖子

DataGrid行请求模式与数据虚拟化

我使用CodePlex的一些想法和Bea Stollnitz的博客以及Vincent Da Ven Berhge的论文(同一链接)实现了数据虚拟化解决方案.但是我需要一种不同的方法,所以我决定编写自己的解决方案.

DataGrid用这个解决方案来显示大约一百万行.我也在使用UI虚拟化.我的解决方案是可行的,但我在某些情况下遇到了一些奇怪的行为,这些行为是关于如何DataGrid从源头请求数据的.

关于解决方案

我最终编写了一份列表来完成所有繁重的工作.它是一个名为VirtualList<T>.It 的泛型类,它实现了ICollectionViewFactory接口,因此集合视图创建机制可以创建一个VirtualListCollectionView<T>实例来包装它.这个类继承自ListCollectionView.我没有按照建议编写我自己的ICollectionView实现.继承似乎也很好.

VirtualList<T>分裂整个数据到页.它获取总项数,每次DataGrid通过列表索引器对行进行请求时,它会加载相应的页面或从缓存中返回.页面在内部回收,并DispatcherTimer在空闲时间处理未使用的页面.

数据请求模式

  • 我学到的第一件事就是VirtualList<T>实现IList(非泛型).否则,ItemsControl它将把它视为一个IEnumerable并查询/枚举所有行.这是合乎逻辑的,因为DataGrid它不是类型安全的,所以它不能使用IList<T>接口.

  • 带有0索引的行经常被问到DataGrid.它似乎用于视觉项目测量(根据调用堆栈).所以,我只是缓存这一个.

  • 内部的缓存机制DataGrid使用可预测的模式来查询它显示的行.首先它要求从上到下的可见行(每行两次),然后它在可见区域(包括第一个可见行)之前查询几行(取决于可见区域的大小)从下到上依次订购.之后,它在从上到下的可见行(包括最后一个可见行)之后请求相同数量的行.

    如果可见行索引是4,5,6.数据请求将是:4,4,5,5,6,6,4,3,2,1,6,7,8,9.

    如果我的页面大小设置正确,我可以从当前和以前加载的页面提供所有这些请求.

  • 如果CanSelectMultipleItemsTrue并且用户使用SHIFT按钮或鼠标拖动选择多个项目,则DataGrid枚举从列表开头到选择结尾的所有行.IEnumerable无论IList是否实现,此枚举都通过接口发生.

  • 如果所选行不可见且当前可见区域与所选行"远",则有时DataGrid会开始请求从所选行到可见区域末尾的所有项目.包括其间甚至不可见的所有行.我无法弄清楚这种行为的确切模式.也许我的实施就是这个原因.

我的问题

  • 我想知道,为什么DataGrid不可见行的请求,因为这些行将在可见时再次请求?

  • 为什么有必要要求每一行两到三次?

  • 任何人都可以告诉我如何使DataGrid不使用IEnumerable,除了关闭多个项目选择?

wpf datagrid data-virtualization

11
推荐指数
1
解决办法
1561
查看次数

通用方法处理IEnumerable与泛型类型不同

请检查以下代码段:

public interface ICountable { }
public class Counter<T>
    where T : ICountable
{
    public int Count(IEnumerable<T> items)
    {
        return 0;
    }

    public int Count(T Item)
    {
        return 0;
    }
}

public class Counter
{
    public int Count<T>(IEnumerable<T> items)
        where T : ICountable
    {
        return 0;
    }

    public int Count<T>(T Item)
        where T : ICountable
    {
        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

Counter的两个版本仅在泛型参数的规范上有所不同.其中一个定义为泛型类型参数,另一个定义为泛型参数.两者都限制方法参数以实现ICountable接口.我将分别称他们为具体非具体.

现在,我定义了一个实现ICountable接口的类,以及一组实例:

public class CItem : ICountable { }
var countables = new List<CItem>(); …
Run Code Online (Sandbox Code Playgroud)

.net c# generics generic-type-argument generic-method

10
推荐指数
1
解决办法
967
查看次数

AspNet.Core,IdentityServer 4:使用JWT承载令牌与SignalR 1.0进行websocket握手期间未授权(401)

我有两个aspnet.core服务.一个用于IdentityServer 4,另一个用于Angular4 +客户端使用的API.SignalR集线器在API上运行.整个解决方案在docker上运行,但这无关紧要(见下文).

我使用隐式身份验证流程,它可以完美运行.NG应用程序重定向到用户登录的IdentityServer的登录页面.之后,浏览器将被重定向回带有访问令牌的NG应用程序.然后,令牌用于调用API并与SignalR建立通信.我想我已经阅读了所有可用的内容(参见下面的资料).

由于SignalR使用不支持头的websockets,因此令牌应该在查询字符串中发送.然后在API端,提取令牌并为请求设置令牌,就像它在标题中一样.然后验证令牌并授权用户.

API在没有任何问题的情况下工作,用户获得授权,并且可以在API端检索声明.因此,IdentityServer应该没有问题,因为SignalR不需要任何特殊配置.我对吗?

当我不使用SignalR集线器上的[Authorized]属性时,握手成功.这就是为什么我认为我使用的docker基础设施和反向代理没有任何问题(代理设置为启用websockets).

所以,没有授权SignalR工作.通过授权,NG客户端在握手期间获得以下响应:

Failed to load resource: the server responded with a status of 401
Error: Failed to complete negotiation with the server: Error
Error: Failed to start the connection: Error
Run Code Online (Sandbox Code Playgroud)

请求是

Request URL: https://publicapi.localhost/context/negotiate?signalr_token=eyJhbGciOiJSUz... (token is truncated for simplicity)
Request Method: POST
Status Code: 401 
Remote Address: 127.0.0.1:443
Referrer Policy: no-referrer-when-downgrade
Run Code Online (Sandbox Code Playgroud)

我得到的回应:

access-control-allow-credentials: true
access-control-allow-origin: http://localhost:4200
content-length: 0
date: Fri, 01 Jun 2018 09:00:41 GMT
server: nginx/1.13.10
status: 401
vary: Origin
www-authenticate: …
Run Code Online (Sandbox Code Playgroud)

c# websocket asp.net-core identityserver4 asp.net-core-signalr

6
推荐指数
2
解决办法
2502
查看次数

如何从标题中获取 Flutter Web 中的 cookie?

Flutter Web 应用程序发送一个 HTTP REST API POST 请求,并在 Set-Cookie 标头中获取一个 JSON 响应和一个 cookie,如下所示。

(Flutter (Channel beta, 1.22.0, on Microsoft Windows)

设置 Cookie 标头

提取 cookie 时,响应似乎没有找到标头值。调用和提取代码为:

var response = await http.post(url, headers: {"Content-Type": "application/json"}, body: jsonEncode(data));

if (response.statusCode == 200) {
  var cookie = response.headers['set-cookie'];
  print('cookie: $cookie');
}
Run Code Online (Sandbox Code Playgroud)

控制台结果是:

cookie: null
Run Code Online (Sandbox Code Playgroud)

服务器端在 Docker 容器中的 ASPNet.Core 3.1 上运行,但是这应该不是问题,因为 cookie 位于标头中。那么,如何在 Flutter Web 中提取它呢?

实际上,我的最终目标是将 cookie 与所有其他请求一起发回。但它似乎不会在浏览器中自动发生。因此,如果有人可以指出处理这种情况的正确方法,这也是一个很好的解决方案。

任何帮助表示赞赏。谢谢。

cookies flutter flutter-web

2
推荐指数
1
解决办法
2034
查看次数