zoukankan      html  css  js  c++  java
  • C# 自定义线程修改UI(一)

    在Wpf中界面显示数据的修改,都是通过UI线程完成,如果尝试从其他线程中直接修改控件的值回抛出异常,“调用线程无法访问此对象,因为另一个线程拥有该对象”。

    例如:http://www.cnblogs.com/tianma3798/p/5762016.html

    解决方案1:通过Invoke或者BeginInvoke将操作发送给Dispatcher 对象,委托Dispatcher去执行UI操作,每个UI控件都有Dispatcher 对象

    代码实例:

    Xaml代码

    <ProgressBar x:Name="progressOne"  
                    Minimum="0" Maximum="1" 
                    Height="30"   Margin="10,85,10,0" 
                    VerticalAlignment="Top"/>
    <!--绑定 进度条的值,并格式化为百分数-->
    <Label x:Name="label" Content="{Binding ElementName=progressOne,Path=Value}" 
            ContentStringFormat="{}{0:P2}"
            HorizontalAlignment="Left" 
            Margin="110,120,0,0"
            FontWeight="Bold" Foreground="Red"
            VerticalAlignment="Top"/>

    C#代码

    //启动前程修改UI数据
    Task.Run(() =>
    {
        int i = 0;
        while (true)
        {
            i++;
            if (i == 100)
                i = 0;
            //定义修改UI委托
            Action<int> action1 = (q) =>
            {
                progressOne.Value = q/100.0;
            };
            progressOne.Dispatcher.BeginInvoke(action1, i);
            Thread.Sleep(100);
        }
    });

    显示:

    解决方案2:使用Wpf的双向绑定,在自定义线程中修改源数据,自动通知到UI线程修改界面显示

    这种方式有个好处,只关心数据的修改,界面多出使用该数据的界面自动修改

    更多双向绑定:http://www.cnblogs.com/tianma3798/p/5765464.html

    代码实例:

    Xaml代码

    <Grid>
        <Slider x:Name="slider" 
                Height="30"
                Value="{Binding Path=Result,Mode=TwoWay}" Minimum="0" Maximum="100"
                Margin="35,120,25,0" VerticalAlignment="Top"/>
        <Label x:Name="label" Content="{Binding Path=Result,Mode=TwoWay}"
                ContentStringFormat="当前值:{0}"
                HorizontalAlignment="Left" 
                FontWeight="Bold" Foreground="Red"
                Margin="95,165,0,0" 
                VerticalAlignment="Top"/>
    </Grid>

    C#代码

    //双向绑定数据
    NumberData data = new NumberData();
    slider.DataContext = data;
    label.DataContext = data;
    //启动线程修改绑定数据,界面内容会同步修改
    Task.Run(() =>
    {
        int i = 0;
        while (true)
        {
            i++;
            if (i == 100) i = 0;
            //修改双向绑定属性
            data.Result = i;
            Thread.Sleep(100);
        }
    });
    /// <summary>
    /// 实现INotifyPropertyChanged接口,通知
    /// </summary>
    public class NumberData : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        private int _Result;
        public int Result
        {
            get { return _Result; }
            set
            {
                _Result = value;
                if (this.PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("Result"));
            }
        }
    }

    更多异步修改UI:http://www.cnblogs.com/tianma3798/p/5766691.html

  • 相关阅读:
    如何配置tomcat的环境变量
    如何配置jdk的本地环境
    如何下载最新版本和旧版本的eclipse?
    用eclipse开发需要准备什么?
    eclipse.ini相关问题
    jquery如何遍历table,并对table里的某一个单元格进行操作
    jquery的Layer弹出框操作
    select列表遍历和触发事件
    Spring AOP详细介绍
    简单介绍Spring的ContextLoaderListener
  • 原文地址:https://www.cnblogs.com/tianma3798/p/5766863.html
Copyright © 2011-2022 走看看