C# WPF 更新状态栏文本和进度来自另一个 window

C# WPF Update Status bar text and progress from another window

我有一个名为 "wpfMenu" 的 Main window,它有一个包含文本块和进度条的状态栏。状态栏需要从主 window 启动的单独 windows 上的 运行 方法更新(任何时候只有一个 window 打开)。

最好我想将最小值、最大值、进度、文本值传递给名为 "statusUpdate" 的 class 以更新进度,但我不知道从哪里开始以及任何更新示例我遇到的进度条是 运行 在同一个 window.

这是我到目前为止的状态栏代码

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:Custom="http://schemas.microsoft.com/winfx/2006/xaml/presentation/ribbon" x:Class="Mx.wpfMenu"
    Title="Mx - Menu" Height="600" Width="1000" Background="#FFF0F0F0" Closed="wpfMenu_Closed">
<Grid>
    <StatusBar x:Name="sbStatus" Height="26" Margin="0,0,0,0" VerticalAlignment="Bottom" HorizontalAlignment="Stretch">
        <StatusBar.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="4*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                </Grid>
            </ItemsPanelTemplate>
        </StatusBar.ItemsPanel>
        <StatusBarItem>
            <TextBlock Name="sbMessage" Text="{Binding statusUpdate.Message}"/>
        </StatusBarItem>
        <StatusBarItem Grid.Column="1">
            <ProgressBar Name="sbProgress" Width="130" Height="18" Minimum="0" Maximum="100" IsIndeterminate="False"/>
        </StatusBarItem>
    </StatusBar>
</Grid>

我的 class 的代码是

    public class statusUpdate : INotifyPropertyChanged
{
    private string _message;
    public event PropertyChangedEventHandler PropertyChanged;

    public statusUpdate()
    {

    }

    public statusUpdate (string value)
    {
        this._message = value;
    }

    public string Message
    {
        get { return _message; }
        set
        {
            _message = value;
            OnPropertyChanged("Message");
        }
    }

    void OnPropertyChanged(string _message)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(_message));
        }
    }
}

这有几个步骤,但它们在其他地方都有很好的记录。这似乎是一个复杂的过程,但这是您将在 WPF 中反复执行的操作。

您将所有设置存储在 class 中是正确的。但是,此 class 需要实施 INotifyPropertyChanged 并在每个 属性 setter.

中引发一个 PropertyChanged 事件
using System.ComponentModel;

public class StatusUpdate : INotifyPropertyChanged
{
    private string message;
    public event PropertyChangedEventHandler PropertyChanged;

    public StatusUpdate()
    {
    }

    public string Message
    {
        get { return this.message; }
        set
        {
            this.message = value;
            this.OnPropertyChanged("Message");
        }
    }

    void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

然后您可以将其设为代码隐藏 class 的 public 属性,并将您的进度条属性绑定到它。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();
    }

    public StatusUpdate Status { get; set; } = new StatusUpdate();

    private void PlayCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
    }

    public void PlayCommand_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        this.Status.Message = "Play";
    }

    public void StopCommand_Executed(object sender, ExecutedRoutedEventArgs e)
    {
        this.Status.Message = "Stop";
    }
}

然后您可以将对相同 class 的引用传递给子窗体,当它们设置任何属性时,WPF 将捕获事件并更新 GUI。

如果您找不到任何这些步骤的示例,请告诉我。

这是您的 XAML 版本,其中包含我在上述示例中使用的绑定和按钮:

<Window x:Class="WpfProgressBar.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfProgressBar"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Window.CommandBindings>
    <CommandBinding Command="Play" Executed="PlayCommand_Executed" CanExecute="PlayCommand_CanExecute" />
    <CommandBinding Command="Stop" Executed="StopCommand_Executed" />
</Window.CommandBindings>
<Grid>
    <StackPanel>
        <Button Content="Play" Command="Play" />
        <Button Content="Stop" Command="Stop" />
    </StackPanel>
    <StatusBar Height="26" Margin="0,0,0,0" VerticalAlignment="Bottom" HorizontalAlignment="Stretch">
        <StatusBar.ItemsPanel>
            <ItemsPanelTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="4*"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                </Grid>
            </ItemsPanelTemplate>
        </StatusBar.ItemsPanel>
        <StatusBarItem>
            <TextBlock Text="{Binding Status.Message, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, NotifyOnSourceUpdated=True}"/>
        </StatusBarItem>
        <StatusBarItem Grid.Column="1">
            <ProgressBar Width="130" Height="18" Minimum="0" Maximum="100" IsIndeterminate="False"/>
        </StatusBarItem>
    </StatusBar>
</Grid>
</Window>

注意,我通常不会像这样进行命令绑定,但不想陷入添加 RelayCommand

的复杂局面