在调度程序中创建用户控件并将其添加到UI中的控件

时间:2011-09-25 13:05:49

标签: c# wpf multithreading xaml dispatcher

我有长时间处理操作,为此必须在backGround中完成,但问题是:

  • 当我创建用户控件,然后将其添加到UI(listView)控件时,WPF不显示UC(用户控件),但listView似乎填充了我创建的相同数量的UC

我使用了backgroundWorker,然后我使用了listView的Dispatcher,然后是主Dispatcher,但是所有问题都是

我想知道我是否可以使用UIThread,但我不知道如何。

我的代码是:

        private void btn_click(object sender, System.Windows.RoutedEventArgs e)
    {

            string path = fileSourcesCombo.SelectedItem.ToString();

            converter = getConverter(path);

            this.Dispatcher.BeginInvoke(new Action(delegate()
            {
                System.Data.DataTable dataTable = converter.getDataTable();
                dataGrid.Dispatcher.Invoke(new Action(delegate()
                {
                    dataGrid.ItemsSource = dataTable.DefaultView;
                }
                ));

                List<MyAttribute> attributes = converter.attributes;

                foreach (MyAttribute attribute in attributes)
                {
                    string name = attribute.name;
                    string type = attribute.type;

                    CustomAttribute customAtt = new CustomAttribute(name, type);
                    ListViewControl.Dispatcher. Invoke(new Action(delegate() { ListViewControl.Items.Add(customAtt); }));
                }
            }
            ),System.Windows.Threading.DispatcherPriority.Background);

        }
  • Converter.getDataTable()需要很长时间。
  • dataGrid.Dispatcer.Invoke正常工作,因为它更新并激动人心的控制。
  • ListViewControl.Dispatcher似乎无法正常工作,也不是this.Dispatcher

正如我之前所说,没有生成编译错误,只是列表视图似乎在我尝试的所有方法上都填充了空项。

编辑:

当我将ListView更改为ListItem时,它工作,但我不知道为什么? 任何我仍然想要使用listView控件..

这是Xaml代码的工作原理:

<Grid Margin="8,0">
<ListView x:Name="testpanel" Margin="8" BorderThickness="0" DisplayMemberPath="" Style="{DynamicResource SimpleListBox}" ItemContainerStyle="{DynamicResource SimpleListBoxItem}">                                         
</ListView>
</Grid>

如果我从:ItemContainerStyle卸下DynemicResource,它不起作用

2 个答案:

答案 0 :(得分:0)

请为您的ListView发布XAML。你可能错过了DisplayMemberPath吗?如果它有项目但不知道要显示什么,那就是它的行为。

答案 1 :(得分:0)

说出什么是罪行是不可能的,但这里有一些可能会有所帮助的事情:

  1. 如果您不使用ListView.View,则应使用ListBox
  2. 如果您向控件添加UI-Elements,则不应使用DisplayMemberPath
  3. BeginInvoke内的所有内容都应该已经在UI线程上,因此内部的其他调度程序调用应该是多余的。 (阅读threading todel reference
  4. 如果在后台线程上调用converter = getConverter(path),则代码中缺少您创建线程的部分,或者发生奇怪的事情,即在代码中调用事件处理程序。
  5. XAML中的控件名为testpanel,但在您调用ListViewControl.Items.Add的代码中,我希望您的代码发布中存在一些不一致。
  6. ItemContainerStyle 可以包含各种会搞砸的事情。