首页 > 解决方案 > 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)

标签: monomonodevelopgtk#

解决方案


问题来了:

在 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;不幸的是并没有做到这一点。您正在创建一个新的参考,是的,但该参考指向原始参考指向的同一对象。

现在,假设我们正在管理具有属性xy的类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)
{
    // ...
}

我认为这会更容易,因为不需要尝试实现传递引用(不可能),也不需要复制树视图。

希望这可以帮助。


推荐阅读