2017-05-04 33 views
0

我尝试做一些简单的任务(我想是这样)。我想从for循环动态地改变GUI。
让我们来看看我的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"> 
    <StackPanel Name="MyPanel"> 
     <TextBlock Text="{Binding MyValue}"></TextBlock> 
     <Button Click="Button_Click">OK</Button> 
     <ListBox Name="myList" ItemsSource="{Binding MyCollection}" > 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <Grid Margin="10"> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="20"/> 
          <ColumnDefinition Width="20"/> 
         </Grid.ColumnDefinitions> 
         <TextBlock Text="{Binding A}" Grid.Column="0"/> 
         <TextBlock Text="{Binding B}" Grid.Column="1"/> 
        </Grid> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
     </ListBox> 
    </StackPanel> 
</Window> 

正如你所看到的,我有一个显示号码的文本块,按钮时启动该程序,并在列表框中,应该显示藏品。

点击该按钮后,第一个文本块(bindes myvalue的)显示动态值,但在列表框中,我得到了一个错误:
“这种类型的CollectionView不会从不同的线程支持更改其SourceCollection从分派器线程。“
我看到了另一个错误的答案,但无法理解如何在我的情况下实现它。

这里的C#代码:

using System; 
using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public static MyModel m; 
     public MainWindow() 
     { 
      m = new MyModel(); 
      InitializeComponent(); 
      MyPanel.DataContext = m; 
     } 

     bool flag = false; 
     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      flag = !flag; 
      Task.Factory.StartNew(() => 
      { 
       for (int i = 0; i < 5000000; i++) 
       { 
        if (flag == false) break; 
        m.MyValue = i.ToString(); 
        m.MyCollection.Add(new ChartPoint { A = i, B = 2 * i }); 
       } 
      }); 
     } 
    } 

    public class MyModel : INotifyPropertyChanged 
    { 
     private string myValue; 


     public ObservableCollection<ChartPoint> MyCollection { get; set; } 

     public MyModel() 
     { 
      MyCollection = new ObservableCollection<ChartPoint>(); 
     } 

     public string MyValue 
     { 
      get { return myValue; } 
      set 
      { 
       myValue = value; 
       RaisePropertyChanged("MyValue"); 
      } 
     } 

     private void RaisePropertyChanged(string propName) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
     } 
     public event PropertyChangedEventHandler PropertyChanged; 
    } 

    public class ChartPoint 
    { 
     public int A { get; set; } 
     public int B { get; set; } 
    } 
} 

非常感谢!

+0

如果你的程序在.NET 4.5或更高版本上运行,那么就没有必要处理'调度。调用'/'Dispatcher.BeginInvoke',只要你想在其他(后台)线程中改变你的集合。只需在'BindingOperations.EnableCollectionSynchronization'的帮助下指示WPF绑定引擎允许除Dispatcher之外的其他线程更改您的ObservableCollection。 [有关相关问题的这个答案]的详细信息(http://stackoverflow.com/a/31600890/2819245)。 – elgonzo

回答

1

我已经改变了Button_Click码了一下,这是你想要实现的,请建议:

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     flag = !flag; 

     var list = new List <ChartPoint>(); 

     Task.Factory.StartNew(() => 
     { 
     for (int i = 0; i < 50000000; i++) 
     { 
      if (flag == false) break; 
      m.MyValue = i.ToString(); 
      Dispatcher.BeginInvoke(new Action(() => 
              { 
               m.MyCollection.Add(new ChartPoint 
                   { 
                    A = i, 
                    B = 2 * i 
                   }); 
              }), 
           DispatcherPriority.Background); 
     } 
     }); 
    } 
+0

太棒了!你能解释一下吗?我在哪里可以读到它? –