当Thread运行时如何在WPF中的UI上显示加载面板 [英] When Thread running how to show loading panel on the UI in WPF

查看:66
本文介绍了当Thread运行时如何在WPF中的UI上显示加载面板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的WPF应用程序中,我有一个带有两个用户控件的主窗口。



我的 Mainwindow.xaml 就像这样

In My WPF application, I have One Mainwindow with two user controls.

My Mainwindow.xaml like this

<Grid Name="MainGrid">
<my:Usercontrol1 HorizontalAlignment="Left" Margin="70,132,0,0" Name="dummy1" VerticalAlignment="Top" />
</Grid>





然后我的 UserControl.Xaml



这里我有一个网格包含连接到数据库的控件,加载需要时间,因为我正在使用一个loadingUserControl,如加载旋转图像。 br $> b $ b



Then my UserControl.Xaml

Here I am having one grid contains controls which is connecting to the database, it will take time to load, for that I am using one loadingUserControl like loading rotating image.

<Grid Height="300" Width="770" >
    <Grid Height="223" Width="334"  Margin="10,80,346,-20">

        <Label Width="90" Height="24" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" FontFamily="Verdana" FontWeight="Normal" Margin="10,37,6,5" Grid.Column="1">Sql Server</Label>
        <Grid Grid.Column="2" Width="200" removed="White" Height="20" Margin="1,39,20,7">
            <ComboBox VerticalAlignment="Top" HorizontalAlignment="Left" removed="Transparent" Style="{StaticResource StyleForWidth200}" Margin="0,0,0,0" Name="cmbServerName" Width="200" Height="20" FontFamily="Verdana" IsEditable="True" StaysOpenOnEdit="True" ClipToBounds="False">

            </ComboBox>
        </Grid>
        <RadioButton Content="Trusted Connection" Grid.Column="2" Height="20" HorizontalAlignment="Left" Name="rbTrustedConnection" VerticalAlignment="Stretch" Width="200" FontFamily="Verdana" FontWeight="Normal" Margin="0,6,0,16" Grid.Row="1" Grid.RowSpan="2" FontSize="10" IsChecked="True" />
        <RadioButton Content="SQL Server Authentication" Grid.Column="2" Grid.Row="2" Height="16" HorizontalAlignment="Left" Name="rbSQLServerAuthentication" VerticalAlignment="Stretch" Width="200" FontFamily="Verdana" FontWeight="Normal" Margin="0,5,0,0" FontSize="10" />
        <Label  Width="90" Height="24" Grid.Row="3" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" FontFamily="Verdana" FontWeight="Normal" Grid.Column="1" Margin="10,9,6,9">User Name</Label>
        <TextBox Grid.Column="2" Grid.Row="3" Name="txtUserName" Width="200" Height="20" HorizontalAlignment="Left" Text="" FontFamily="Verdana" FontWeight="Normal" Margin="0,11"></TextBox>
        <Label  Width="90" Height="24" Grid.Row="4" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" FontFamily="Verdana" FontWeight="Normal" Grid.Column="1" Margin="10,2,6,2">Password</Label>
        <PasswordBox Grid.Column="2" Grid.Row="4" Width="200" Height="20" HorizontalAlignment="Left" FontFamily="Verdana" Name="txtPwdWord"/>
        <Button Grid.Column="2" Grid.Row="5" Name="btnConnect" Width="70" Height="30" Margin="131,0,20,5" Content="Connect" FontFamily="Verdana" FontWeight="Normal" Focusable="True" Style="{StaticResource NormalStyle11}" Click="btnConnect_Click"></Button>

        <my:LoadingControl x:Name="loadingControl1" Margin="0,70,0,0" Visibility="Visible" />
    </Grid>
</Grid>





In My代码后面的 UserControl1.cs

这里我使用线程

当它的加载数据库,LoadingControl应该旋转,一旦数据库加载了loadingControl应该被隐藏,为此我实现了以下代码。



这里我的问题是LoadingControl不是roatating并且应用程序获取挂起,但是当数据库加载lodingcontrol时被隐藏。



你能不能弄清楚我错过了什么。





In My code behind UserControl1.cs
here I am using threading
when its loading database, LoadingControl should be rotate,once database loaded loadingControl should be hidden, for that I implemented the following code.

here my problem is LoadingControl is not roatating and application get hangs, but when the database loaded lodingcontrol being hidden.

can you please figure out what I missed here.

private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            BindInstances = new Thread(new ThreadStart(ServerConnection));
            BindInstances.Start();

        }
private void ServerConnection()
        {

            if (Dispatcher.CheckAccess())
            {
                BindDefaultInstances(); 
                loadingControl1.Visibility = Visibility.Hidden;
            }
            else
            {
                Dispatcher.BeginInvoke(DispatcherPriority.Normal,new Action(ServerConnection));
            }

private void BindDefaultInstances()
        {
            DataAccess objIED_DAL = new DataAccess();
          
            DataTable dtInstanceList = new DataTable();
            dtInstanceList = objIED_DAL.GetInstances();
            if (dtInstanceList.Rows.Count > 0)
            {
                foreach (DataRow dr in dtInstanceList.Rows)
                {
                    cmbServerName.Items.Add(dr["ServerName"]);
                }
            }
        }

推荐答案

你在做什么?!您从 ServerConnection 发送 ServerConnection !这是你的错误。



就是这样。考虑一下。您可能不明白 Dispatcher 的作用。您应该做一些几乎相反的事情:委托实例传递给 Dispatcher.Invoke Dispatcher.BeginInvoke 应该快速在UI中显示内容的方法。这个方法实际上将在UI线程中调用。



请参阅我过去的答案以获取更多信息:

Control.Invoke()与Control.BeginInvoke() [ ^ ],

Treeview扫描仪和MD5的问题 [ ^ ],

如何在vb.net中的另一个线程上运行keydown事件 [ ^ ],

在启用禁用+多线程后控制事件未触发 [ ^ ]。



(对不起,我的答案中的一些信息与 System.Windows.Forms 有关,一些用于WPF,有些用于两者。在这种情况下,忽略与表格相关的任何内容。)



-SA
What are you doing?! You are dispatching ServerConnection from ServerConnection! This is your bug.

That''s it. Just think about it. You probably don''t understand what Dispatcher does. You should be doing something nearly opposite: the delegate instance passed to Dispatcher.Invoke or Dispatcher.BeginInvoke should be a quick method showing something in the UI. This method will be actually called in the UI thread.

Please see my past answers for more information:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^],
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

(Sorry, some information in my answers is related to System.Windows.Forms, some for WPF, some for both. In you case, ignore anything related to Forms.)

—SA


正如谢尔写的那样,你的错误是你在UI线程中调用 ServerConnection 方法。这个连接工作是在UI线程上完成的,那就是你的UI挂起的东西。尝试更改 ServerConnection 方法,以仅调用UI线程中的UI更改。类似于:

As Sergey wrote, your mistake is that you invoke the ServerConnection method in the UI thread. That connection work is done on the UI thread and, that what hangs your UI. Try to change the ServerConnection method to only invoke the UI changes in the UI thread. Something like:

private void ServerConnection()
{
    DataAccess objIED_DAL = new DataAccess();

    DataTable dtInstanceList = new DataTable();
    dtInstanceList = objIED_DAL.GetInstances();

    if (dtInstanceList.Rows.Count > 0)
    {
        foreach (DataRow dr in dtInstanceList.Rows)
        {
            Dispatcher.BeginInvoke(new Action(() => cmbServerName.Items.Add(dr["ServerName"])));
        }
    }

    Dispatcher.BeginInvoke(new Action(() => loadingControl1.Visibility = Visibility.Hidden));
}


这篇关于当Thread运行时如何在WPF中的UI上显示加载面板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆