C# WPF。多线程时绑定属性更改但 UI 不更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17889617/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:17:45  来源:igfitidea点击:

C# WPF. Binding Property Change but UI not updating when multi-threading

c#wpfbinding

提问by tinymins

I have a project, where I bind TextBlock's Text property with a get/set in the codebehind. However, when the application loads, changing binding property can not update the ui.

我有一个项目,我在代码隐藏中使用 get/set 绑定 TextBlock 的 Text 属性。但是,当应用程序加载时,更改绑定属性无法更新 ui。

MainWindow.xaml:

主窗口.xaml:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ListBox SelectionMode="Multiple" x:Name="lstFileManager" HorizontalContentAlignment="Stretch" Background ="Transparent" ItemsSource="{Binding}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid Visibility="{Binding ui_visiable}" Margin="5,0,0,0">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition Height="Auto" />
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="{Binding ui_complete_percentage}"/>
                            <ColumnDefinition Width="{Binding ui_incomplete_percentage}"/>
                        </Grid.ColumnDefinitions>
                        <Rectangle Opacity="0.8" Grid.RowSpan="2" Grid.Column="0" Fill="{Binding ui_complete_color}" />
                        <Rectangle Opacity="0.8" Grid.RowSpan="2" Grid.Column="1" Fill="{Binding ui_incomplete_color}"/>
                        <TextBlock Margin="20,10,20,10" Text="{Binding ui_tip_text}" Grid.ColumnSpan="2" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Left" MinHeight="20" FontSize="12" FontFamily="Microsoft YaHei"/>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="HorizontalAlignment" Value="Stretch"/>
                    <Setter Property="Margin" Value="0,0,0,1"/>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
    </Grid>
</Window>

MainWindow.xaml.cs:

主窗口.xaml.cs:

using System;
using System.Collections.ObjectModel;
using System.Threading;
using System.Windows;
using System.Windows.Threading;

namespace WpfApplication1 {
    /// <summary>
    /// MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window {

        public MainWindow() {
            InitializeComponent();
            Bind();
            RefreshFileList();
        }

        #region DataBind
        public class FileListViewItem {
            public string ui_visiable { get; set; }
            public string ui_complete_percentage { get; set; }
            public string ui_incomplete_percentage { get; set; }
            public string ui_complete_color { get; set; }
            public string ui_incomplete_color { get; set; }
            public string ui_tip_text { get; set; }
        }
        ObservableCollection<FileListViewItem> FileListViewItemGroup = new ObservableCollection<FileListViewItem>();
        public void Bind() {
            lstFileManager.ItemsSource = FileListViewItemGroup;
        }
        #endregion

        #region Refresh File List
        private void RefreshFileList() {
            //new Thread((process) => {
                Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => {
                    FileListViewItemGroup.Clear();
                }));
                for (int i = 0; i < 10; i++) {
                    FileListViewItem flvi = new FileListViewItem {
                        ui_tip_text = "1",
                        ui_visiable = "Visiable",
                        ui_complete_percentage = "0*",
                        ui_incomplete_percentage = "100*",
                        ui_complete_color = "White",
                        ui_incomplete_color = "#FFFF43FF"
                    };
                    Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => {
                        FileListViewItemGroup.Add(flvi);
                    }));
                }
                // those code below did not make sence when I am using mutli-threading.
                FileListViewItemGroup[0].ui_complete_percentage = "100*";
                FileListViewItemGroup[0].ui_incomplete_percentage = "0*";
                FileListViewItemGroup[0].ui_tip_text = "what's wrong!";
            //}).Start();
        }
        #endregion

    }
}

The problem is that when I'm trying to use multi-thread, those code (FileListViewItemGroup[0].ui_complete_percentage = "100*";) will not work.

问题是,当我尝试使用多线程时,那些代码 (FileListViewItemGroup[0].ui_complete_percentage = "100*";) 将不起作用。

I've working on it the whole night and I don't know why. Any body can fix the code or have some explain to help me out? Thanks.

我整晚都在研究它,我不知道为什么。任何机构都可以修复代码或有一些解释来帮助我?谢谢。

回答by u4370109

(Problem solved in the comments and by question edit from the OP. Converted into a community wiki answer. See Question with no answers, but issue solved in the comments (or extended in chat))

(问题在评论中解决,并通过来自 OP 的问题编辑解决。转换为社区 wiki 答案。请参阅没有答案的问题,但问题已在评论中解决(或在聊天中扩展)

The OP wrote:

OP写道:

Problem solved, here is my code:

问题解决了,这是我的代码:

 #region DataBind
    public class FileListViewItem : INotifyPropertyChanged
    {
        public string ui_visiable { get; set; }
        public string ui_complete_percentage { get; set; }
        public string ui_incomplete_percentage { get; set; }
        public string ui_complete_color { get; set; }
        public string ui_incomplete_color { get; set; }
        private string _ui_tip_text;
        public string ui_tip_text
        {
            get { return _ui_tip_text; }
            set
            {
                _ui_tip_text = value;
                RaisePropertyChanged("ui_tip_text");
            }
        }

        #region Implement INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        public void RaisePropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
    ObservableCollection<FileListViewItem> FileListViewItemGroup = new ObservableCollection<FileListViewItem>();
    public void Bind() {
        lstFileManager.ItemsSource = FileListViewItemGroup;
    }
    #endregion

Thanks PoweredByOrange and Nick for their help :)

感谢 PoweredByOrange 和 Nick 的帮助:)