Привязка свойства text текстового блока в StatusBar с разных страниц

У меня есть приложение WPF, в котором есть MainWindow, который разделен на 2 фрейма: один для левого меню навигации, а другой для страниц (например, страница addFirm, страница addlocation и т. д.). Теперь мне нужна строка состояния в главном окне, которая должна отображать сообщения, поднятые на страницах. Что-то вроде этого

<DockPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch" LastChildFill="True"  >
    <StackPanel DockPanel.Dock="Top" Style="{DynamicResource SMMainStackPanel}" >
        <Border Style="{DynamicResource SMBorder}"  >
          <Label Content="System" FontSize="18" HorizontalContentAlignment="Center" />
        </Border>
    </StackPanel>
    <StackPanel DockPanel.Dock="Left" Style="{DynamicResource SMMainStackPanel}">
        <Border VerticalAlignment="Stretch" Style="{DynamicResource SMBorder}"  >
            <Frame Name="frame1" Source="Menu.xaml" Style="{DynamicResource SMMainFrame}" />
        </Border>
    </StackPanel>
    <StackPanel Style="{DynamicResource SMMainStackPanel}" >
       <Border Style="{DynamicResource SMBorder}" >                
            <Frame Name="frame2" Style="{DynamicResource SMMainFrame}"/>
        </Border>
        <DockPanel  VerticalAlignment="Stretch" HorizontalAlignment="Stretch" DockPanel.Dock="Bottom">
                   <StatusBar>
                    <StatusBar.ItemsPanel>
                        <ItemsPanelTemplate>
                            <Grid>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*"/>
                                </Grid.RowDefinitions>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="4*"/>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                            </Grid>
                        </ItemsPanelTemplate>
                    </StatusBar.ItemsPanel>
                    <StatusBarItem>
                        <TextBlock>Ready</TextBlock>
                    </StatusBarItem>
                    <StatusBarItem Grid.Column="1">
                        <ProgressBar Value="30" Width="80" Height="18"/>
                    </StatusBarItem>
                    <StatusBarItem Grid.Column="2">
                    <TextBlock Text= "ABC" />
                    </StatusBarItem>
                    <StatusBarItem Grid.Column="3">
            <TextBlock Text="{Binding Source={x:Static sys:DateTime.Now}}"/>
                    </StatusBarItem>
                </StatusBar>
        </DockPanel>
    </StackPanel>
</DockPanel>

Теперь я хочу заполнить StatusBarItem из свойства сообщения нижеприведенного класса вместо статического текста «ABC». PS: объект этого класса создается на отдельных страницах, а не в главном окне.

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

    private void OnPropertyChanged(String property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

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

}

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

Единственная ссылка, которую мне не хватает, это то, как мне получить экземпляр этого класса, который установлен на странице (скажем, предположим, на addlocation) в mainwindow.xaml. Также как мне привязать этот экземпляр к текстовому свойству текстовой области.


person Rachit    schedule 22.01.2014    source источник


Ответы (3)


Если ваш объект StatusHelper является DataContext панели, показанной выше, то настроить привязку в XAML несложно:

<TextBlock Text="{Binding Message}" />

Если, например, эта панель имеет объект PageViewModel в качестве своего DataContext, который содержит свойство StatusHelper с именем «Статус», вы можете связать его следующим образом:

<TextBlock Text="{Binding Status.Message}" />

Точный ответ зависит от того, как вы настроили иерархию модели представления/контекста данных.

person Pieter Witvoet    schedule 22.01.2014
comment
Спасибо за ваш ответ. Панель выше не имеет установленного контекста данных в настоящее время. Также проблема в том, что объект класса StatusHelper создается на уровне страницы, и я не могу понять, как я могу получить к нему доступ в главном окне. Другой вариант, о котором я думал, заключался в использовании статического класса и установке свойств, однако я снова застрял при доступе к объекту этого класса. Вариант, который приходит мне на ум, — создать общий элемент управления для строки состояния, а затем использовать его на каждой странице, однако в данный момент это не выглядит привлекательным для меня. - person Rachit; 22.01.2014
comment
У вас есть MainWindow, которому необходимо отображать содержимое страницы, а также сообщение о состоянии текущей страницы. Затем просто сохраните ссылку на модель представления текущей страницы в модели представления (контексте данных) MainWindow, например, как свойство с именем CurrentPage. Тогда привязка будет следующей: {Binding CurrentPage.Status.Message}. Вы знакомы с MVVM? - person Pieter Witvoet; 22.01.2014

Если у вас его еще нет, добавьте в приложение базовый класс модели представления. Добавьте в приложение класс, реализующий шаблон Singleton, чтобы быть только одним из его экземпляров. Добавьте ссылку на этот класс в свою базовую модель представления, обеспечив доступ к нему только с помощью свойства Instance:

public StateManager StateManager
{
    get { return stateManager.Instance; }
}

Теперь каждая модель представления в вашем приложении имеет доступ к свойствам этого класса, поэтому вы можете привязывать к ним данные из каждого представления:

<TextBlock Text= "{Binding StateManager.YourPropertyName}" />
person Sheridan    schedule 22.01.2014
comment
Шеридан спасибо за ответ. Я понял, что вы предлагаете, но я достиг этого по-другому. Я бы попытался сделать это также, так как это выглядит более аккуратно с точки зрения реализации. - person Rachit; 23.01.2014

Я получил ответ на этот вопрос. Что я сделал, так это передал экземпляр главной страницы общему вспомогательному классу (который является статическим) в статической переменной. Теперь создайте свойство на главной странице, которое будет возвращать экземпляр строки состояния (sbMain). Вызовите вспомогательный класс состояния из основных форм и вызовите для него метод обновления.

Добавьте свойство SmStatusBar в MainWindow, а также передайте экземпляр в главное окно в класс во время инициализации главной страницы, как показано ниже.

    public SmStatusBar StatusBar 
    {
        get { return this.sbMain; }
    }

    public MainWindow()
    {
        InitializeComponent();
        CommonHelper.SmMainWindow = this;
    }

Добавьте статическое свойство в класс Common Helper.

    public static MainWindow MainWindow { get; set; }

Теперь создайте класс StatusHelper.

public static class StatusHelper
{
    private static SmStatusBar _statusBar;

    static StatusHelper()
    {
        _statusBar = CommonHelper.SmMainWindow.StatusBar;
    }

     public static bool UpdateStatus(string text)
     {
         _statusBar.UpdateStatusText(text);
         return true;
     }

}
person Rachit    schedule 23.01.2014