0

上部領域 (プロセスの状態に応じて) にユーザー コントロールとボタンを含む次のウィンドウがあります。ボタンをクリックすると、1 つのユーザー コントロールが非表示になり、別のユーザー コントロールが表示されます。最初のコントロールから 2 番目のコントロールへの変更により、2 番目のコントロールがタスクで終了するまで、ウィンドウは固定されます。

2 番目のコントロールには、手順を記録する ListView が含まれています。プロセス中にこのログを直接見たいです。しかし、私はすべてが終わったときにしか見ることができません。2 番目のコントロールが機能する前にウィンドウを更新するにはどうすればよいですか?

のようなコード行

Me.UpdateLayout()

動作しません...

プログラム全体は、3 つの画面 (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

返信ありがとうございます。

編集: プログラムは3つのステップで構成されています。最初のステップでは、何をするかを設定します。

ステップ 1: 構成する

右下のボタンをクリックすると、2 番目のステップのリストに表示されるマークされた項目 (緑のボタン、赤は無視されます) ごとに何かが実行されます。

ステップ 2: ロギング

ステップ 2 が完了すると、終了画面が表示され、プログラムを閉じることができます (この画面はまだ設計中です)。

ステップ 3: 終了

WinForms と ASP.NET でも、今回と同じ方法でユーザー コントロールを表示および非表示にします (これも、適切な実装が行われる前ではなかった可能性があります)。WPFにもっと良い可能性があるといいのですが。

4

1 に答える 1

0

ここでの問題は、ビューによって表示される要素を更新できる唯一の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 の問題はまだあります。

UI の応答性を維持するためにコード ビハインドから行っていることについてBackgroundWorkersなどを使用して、メイン スレッドからの作業のオフロードを検討する必要があります。次に、UI コントロールを更新する必要があるときはいつでも、それに応じて UI スレッドに通知します。

于 2013-04-15T15:56:03.053 に答える