mono - gtk#:树视图对象始终作为引用调用传递
问题描述
似乎我在处理树视图的方法调用中的参数总是作为引用调用完成的。
我在顶层窗口上有一个可见的 GTK“树视图”控件。数据由各自的模型写入。
现在我想删除一些列(基于用户设置的选项)并将操纵的树视图传递给导出函数。
为了只从输出中删除列,而不是从 GUI 本身中删除,我想将可见的树视图控件复制到一个临时控件中,操作临时控件并在临时控件上调用导出功能。
我的问题是:即使我将我的原点、可见树视图作为值引用(据我的理解)传递,原点将被操纵,并且列的删除将在可视树视图上完成。
似乎我在方法调用中的参数总是作为引用调用完成的。
代码:
“treeview1”是视觉 Gtk.Tree 视图...
我调用我的导出功能:
...
TreeView treeviewExport = SetExportViewAccordingToCheckboxes(treeview1);
ExportFile(treeviewExport);
...
在 SetExportViewAccordingToCheckboxes() 方法中,我只是将全局 treeview1 作为按值调用传递,在内部对其进行操作并返回操作后的树视图:
protected static TreeView SetExportViewAccordingToCheckboxes(TreeView tvSource)
{
TreeView tvRet = tvSource;
if (cbName == false)
tvRet.RemoveColumn( ... );
...
return tvRet;
}
但是即使我已经从内部树视图“tvRet”中删除了列,我的可视控件“treeview1”缺少从“tvRet”中删除的所有列;看起来“treeview1”是作为引用调用传递的。
问:为什么会这样?
注意:我也尝试了关键字“in”,这没有区别:
protected static TreeView SetExportViewAccordingToCheckboxes(in TreeView p_tvSource)
解决方案
问题来了:
在 SetExportViewAccordingToCheckboxes() 方法中,我只是将全局 treeview1 作为按值调用传递,在内部对其进行操作并返回操作后的树视图:
protected static TreeView SetExportViewAccordingToCheckboxes(TreeView tvSource) { TreeView tvRet = tvSource; if (cbName == false) tvRet.RemoveColumn( ... ); ... return tvRet; }
首先是一些背景。在 C# 术语中,值类型是直接包含值的类型,而引用类型是引用数据而不是直接保存数据的类型。
因此,int x = 5
意味着您正在创建整数类型的值对象 5,并将其存储在 中x
,而TreeView tree = new TreeView()
意味着您正在创建TreeViewtree
类型的引用,它指向相同类型的对象。
所有这一切都意味着您不能按值传递对象,即使您愿意。在最好的情况下,您通过值传递引用,这没有任何效果。
因此,下一步是复制数据,并修改复制的对象而不是原始对象。这在理论上是合理的,但这条线:TreeView tvRet = tvSource;
不幸的是并没有做到这一点。您正在创建一个新的参考,是的,但该参考指向原始参考指向的同一对象。
现在,假设我们正在管理具有属性x和y的类Point而不是TreeView的对象。
class Point {
public int X { get; set; }
public int Y { get; set; }
}
您可以轻松创建一个点:
Point p1 = new Point { X = 5, Y = 7 };
但这并没有复制它:
Point p2 = p1;
这会做:
Point p2 = new Point { X = p1.X, Y = p1.Y };
现在最初的问题是您想将几列传递给Export()函数。在这种情况下,您只需将过滤列的向量传递给导出函数,而不是TreeView的副本。
void PrepareExporting()
{
var columns = new List<TreeViewColumn>();
foreach(TreeViewColumn col in this.treeView.Columns) {
if ( this.Filter( col ) ) {
columns.add( col );
}
}
this.Export( columns.ToArray() );
}
void Export(TreeViewColumn[] columns)
{
// ...
}
我认为这会更容易,因为不需要尝试实现传递引用(不可能),也不需要复制树视图。
希望这可以帮助。
推荐阅读
- nginx - 多个反应应用程序未在 nginx 中运行
- python - Numpy 将非零元素从一个数组复制到另一个(3D 数组)
- python - Pandas - 基于其他列创建新列,不包括第一行
- javascript - 管理根据对象内的两个值合并两个数组
- java - 在 Google 地图上更改位置后更新 TextView
- python - 预测 NaN、无穷大或对于 dtype('float64') 来说太大的值
- php - 每次尝试的 Laravel Google Authenticator 应用程序无效代码
- cxf - 请求标头中的 Keycloak 身份验证用户
- awk - sh 按匹配的列名值打破 CSV 文件,同时保留标题
- android - 'Iterable 类型的值
' 不能从函数 '_recentTransactions' 中返回,因为它的返回类型为 'List