【问题标题】:C# WPF Update Status bar text and progress from another windowC# WPF 更新状态栏文本和来自另一个窗口的进度
【发布时间】:2018-11-27 16:13:41
【问题描述】:

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

最好我想将最小值、最大值、进度、文本值传递给一个名为“statusUpdate”的类来更新进度,但我不知道从哪里开始,我遇到的任何更新进度条的例子都是在同一个窗口上运行。

这是我目前的状态栏代码

<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>

我的课的代码是

    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));
        }
    }
}

【问题讨论】:

    标签: c# wpf xaml progress-bar statusbar


    【解决方案1】:

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

    您可以将所有设置存储在一个类中。但是这个类需要实现 INotifyPropertyChanged 并在每个属性设置器中引发一个 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));
            }
        }
    }
    

    然后你可以让它成为你的代码隐藏类的公共属性,并将你的进度条属性绑定到它。

    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";
        }
    }
    

    然后您可以将同一类的引用传递给子窗体,当它们设置任何属性时,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 的复杂性

    【讨论】:

    • 我用我的 statusUpdate 类更新了帖子并更改为绑定,我认为我现在需要做的就是将引用传递给子表单,前提是我所做的事情是正确的。
    • 我只有一个小问题,它可能很简单,尽管将类和字符串设置为公共我无法访问字符串来分配值
    • 你得到了什么错误,你的代码是什么样的?
    • 我在尝试使用“statusUpdate”从我的子表单访问 statusUpdate 类时没有收到错误。要访问该类,唯一显示的是“Equals”和“ReferenceEquals”,我的子表单也必须订阅属性更改事件
    • 如果这些是唯一的选项,您可能会将 statusUpdate 类作为对象传递。要么更改属性类型,要么将其转换为正确的类型。无需订阅该事件,除非您的一个子表单中的代码需要在另一个子表单更改时得到通知。 WPF 自动订阅事件以更新 GUI。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多