【问题标题】:how to use ref to a property in c#如何在 C# 中使用 ref 到属性
【发布时间】:2012-05-12 14:30:08
【问题描述】:

我使用 WPF 来编写我的界面。我使用 ListView 作为我的任务列表。任务列表包含两列,文件名,进度。每一行绑定到一个 TaskInfo:

public class TaskInfo : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public TaskInfo(string fp)
    {
        FileSystemInfo fsi= new DirectoryInfo(fp);
        FileName = fsi.Name;   
        FilePath = fp;     
        PbValue = 0;

    }
    private int pbvalue;
    public int PbValue
    {
        get { return pbvalue; }
        set
        {
            pbvalue = value;
            onPropertyChanged("PbValue");
        }
    }
    private string filename;
    public string FileName
    {
        get { return filename;}
        set
        {
            filename = value;
            onPropertyChanged("FileName");
        }
    }
    private string filepath;
    public string FilePath
    {
        get { return filepath;}
        set
        {
            filepath = value;
            onPropertyChanged("FilePath");
        }
    }

    private void onPropertyChanged(string name)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}

在Progress 列中,它包含一个ProgressBar,将它的Value 绑定到PbValue。 但是由于某种原因,我应该使用C语言编写的Dll。 我使用的功能是:

WaterErase(char * filepath, int * pbvalue)

我在 c# 中确定了它:

public extern static void WaterErase(string filepath, ref int pbvalue)

为了执行多任务,我写了一个线程:

class TaskThread
{
    private TaskInfo taskinfo = null; //task information
    private Thread thread;
    public TaskThread(TaskInfo _taskinfo)
    {
        taskinfo = _taskinfo;
    }
    private void run()
    {   

        WaterErase(taskinfo.FilePath, ref taskinfo.PbValue);

    }       
    public void start()
    {
        if (thread == null)
        {
            thread = new Thread(run);
            thread.Start();
        }
    }
}

但行:

WaterErase(taskinfo.FilePath, ref taskinfo.PbValue);

有问题:

属性、索引器或动态成员访问不能作为 out 或 ref 参数传递

我知道为什么会出现这个问题,但是如何解决这个问题以实现实时更改 PbValue 的功能。这样我就可以直观的在ProgressBar中执行任务进度了

【问题讨论】:

    标签: c# properties ref


    【解决方案1】:

    正如错误所说,您不能这样做。但是您可以为此使用局部变量:

    int temp = taskinfo.PbValue;
    WaterErase(taskinfo.FilePath, ref temp);
    taskinfo.PbValue = temp;
    

    【讨论】:

    • 但是不会实时显示进度。当WaterErase功能完成后,ProgressBar的Value会直接变成100
    【解决方案2】:

    你不能。 ref 值的语义不同于“setter”的语义。考虑改为传递Action<T>

    Action<int> setter = x => ctrl.SomeProp = x;
    Something(setter);
    

    然后:

    {some loop} {
        ...
        callback(latestValue);
    }
    

    但是!还要记住,UI 通常不会在循环内更新,除非您使用多个线程并在线程之间进行适当的传递(以上不是)。

    【讨论】:

    • 我认为本地函数的签名在这里给出,它不会接受委托。
    • @svick 很公平。这使答案更简单:“不”
    • 或者你对Dll有什么建议吗?
    猜你喜欢
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多