【问题标题】:WPF: Show and hide user controls after user interactionWPF:用户交互后显示和隐藏用户控件
【发布时间】:2013-04-07 17:02:58
【问题描述】:

我有以下窗口,其中包含上部区域的用户控件(取决于进程的状态)和一个按钮。单击按钮后,将隐藏一个用户控件,并显示另一个用户控件。通过从第一个控件到第二个控件的更改,窗口被冻结,直到第二个控件完成任务。

第二个控件包含一个记录步骤的 ListView。我想在此过程中直接查看此日志记录。但我只能在一切完成后才能看到它。如何在第二个控件开始工作之前刷新窗口?

类似的代码行

Me.UpdateLayout()

没用……

整个程序应该是一个具有三个屏幕的更新工具(1. 设置,2. 更新过程的记录,3. 完成对话框)。因此,我需要在完成后直接了解日志记录的单个步骤。

我当前的 XAML 如下:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:SiS.Controls="clr-namespace:SiSConverter"
    Title="Konvertierung von SiS-Anwendungen"
    Height="400" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="50px" />
        </Grid.RowDefinitions>

        <SiS.Controls:Settings x:Name="ucSettings" />
        <SiS.Controls:Upgrade x:Name="ucUpgrade" />
        <SiS.Controls:Finish x:Name="ucFinish" />

        <Button Name="btnContinue" Width="100px" Height="30px" Grid.Row="1" Margin="0,0,10,0" HorizontalAlignment="Right" />
    </Grid>
</Window>

以及后面对应的代码:

Class MainWindow 

    Private _Step As Integer = -1
    Private Property [Step] As Integer
        Get
            Return _Step
        End Get
        Set(value As Integer)
            _Step = value

            Me.ucSettings.Visibility = Visibility.Collapsed
            Me.ucUpgrade.Visibility = Visibility.Collapsed
            Me.ucFinish.Visibility = Visibility.Collapsed
            Me.btnContinue.Content = "Weiter"

            Select Case _Step
                Case 0
                    Me.ucSettings.Visibility = Visibility.Visible
                Case 1
                    Me.ucUpgrade.Visibility = Visibility.Visible
                Case 2
                    Me.ucFinish.Visibility = Visibility.Visible
                    Me.btnContinue.Content = "Beenden"
                Case Else
            End Select

            Me.UpdateLayout() 'doesn't work
        End Set
    End Property

    Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
        Me.Step = 0

        For Each Item As System.IO.FileInfo In New System.IO.DirectoryInfo("Converters").GetFiles()
            Dim oConverter As ISiSConverter = System.Reflection.Assembly.LoadFrom(Item.FullName).CreateInstance("Upgrade.Main", True)
            Me.ucSettings.Converters.Add(oConverter)
        Next
    End Sub

    Private Sub btnContinue_Click(sender As Object, e As RoutedEventArgs) Handles btnContinue.Click
        Select Case Me.Step
            Case 0 'Einstellungen
                Me.Step += 1

                Me.btnContinue.IsEnabled = False

                Me.ucSettings.Converters.FindAll(Function(item) item.DoUpgrade).ForEach(Sub(item) item.Upgrade())

                Me.btnContinue.IsEnabled = True
            Case 1 'Upgrade
                Me.Step += 1
            Case 2 'Abschluss
                Me.Close()
            Case Else
        End Select
    End Sub
End Class

感谢您的回复。

编辑: 该程序包括三个步骤。第一步将配置要做什么。

点击右下角的按钮将对每个标记的项目进行一些操作(绿色按钮,红色将被忽略),如第二步列表所示。

如果步骤 2 完成,将显示完成屏幕并且可以关闭程序(此屏幕仍在设计中)。

在 WinForms 和 ASP.NET 中,我也以我这次的方式显示和隐藏用户控件(也许这也不是在一个好的实现之前)。如果 WPF 中有更好的可能性就好了。

【问题讨论】:

  • 我不知道您要做什么,但是您的代码一团糟(无意冒犯)。不得在 WPF 的代码中操作 UI 元素的属性。发布您需要的屏幕截图,我可以告诉您在 WPF 中实现它的正确方法。
  • 如果我明天回到办公室,我会发布截图。
  • 已添加截图。

标签: wpf vb.net user-interface user-controls


【解决方案1】:

您的问题是您的 UI 线程,它是唯一可以更新视图/窗口显示的元素的线程太忙于运行您的

Me.ucSettings.Converters.FindAll(Function(item) item.DoUpgrade).ForEach(Sub(item) item.Upgrade())

^^ 函数,因此在完成之前无法更新视图/渲染元素。

一种“作弊”来明确显示这一点(仅将其用作信息,不要在您的代码中使用它)

Application.Current.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,
                                                   Sub()
                                                     Me.ucSettings.Converters.FindAll(Function(item) item.DoUpgrade).ForEach(Sub(item) item.Upgrade())
                                                   End Sub)

^^ 单击按钮时将显示您的新UserControl。但是,您仍然遇到 UI 无响应的问题。

您需要通过使用 BackgroundWorkers 之类的东西来查看从主线程卸载工作,以了解您在代码隐藏中所做的工作以保持 UI 响应,然后在您需要更新 UI 控件时相应地通知 UI 线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    • 2012-12-13
    • 2018-05-01
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    相关资源
    最近更新 更多