Текст строки состояния обновления C # WPF и прогресс из другого окна - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть главное окно с именем "wpfMenu" со строкой состояния, которая содержит текстовый блок и индикатор выполнения.Строка состояния должна быть обновлена ​​с помощью методов, которые выполняются в отдельных окнах, запускаемых из главного окна (только одно окно открыто в любое время).

Желательно, чтобы я передал min, max, progress, textЗначения для класса с именем «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));
        }
    }
}

1 Ответ

0 голосов
/ 27 ноября 2018

Есть несколько шагов к этому, но все они хорошо документированы в другом месте.Это может показаться сложным процессом, но это то, что вы будете делать снова и снова в 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));
        }
    }
}

Затем вы можете сделать его публичным свойством класса code-behind и привязать к нему свойства индикатора выполнения.

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 перехватит событие и обновит графический интерфейс.

ПустьЯ знаю, если вы не можете найти пример для любого из этих шагов.

Вот версия вашего 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>

NBЯ бы обычно не делал привязки команд, как это, но не хотел вдаваться в сложности добавления RelayCommand

...