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"));
            }
        }
    }

    
    
  • 相关阅读:
    MCU软件最佳实践——独立按键
    MCU软件最佳实践——矩阵键盘驱动
    MCU软件最佳实践——使用printf打印数据
    CAP定理图解证明
    类型和变量
    数字ID过长 精度丢失 (已解决:后端方案)
    Springboot 异步线程池配置(小型应用)
    Java 数字 字符串 简单操作
    Java 网络请求
    Java 时间 日 周 月 季 年
  • 原文地址:https://www.cnblogs.com/sjqq/p/6627957.html
Copyright © 2011-2022 走看看