0

I have a WPF application which has a MainWindow which is divided into 2 frames one for the left navigation menu and the other for the pages (like addFirm page , addlocation page etc). Now i want a status bar on the main window which must display messages which are raised in the pages. Something like this

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

Now i want to populate the StatusBarItem from the message property of the below class instead of the static text "ABC". PS: The obejct of this class is created on the indivisual pages and not on the mainwindow

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

}

I create the object of this class on the indivisual pages and then when an operation is completed then how i set the message property of this class.

The only link which i am missing is that how do i get the instance of this class which is set on a page (say suppose on addlocation) on the mainwindow.xaml. Also how do i bind this instance on the text property of the text area.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
Rachit
  • 136
  • 1
  • 7

3 Answers3

0

If your StatusHelper object is the DataContext of the panel you've shown above, then setting up the binding in XAML is easy:

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

If, for example, that panel has a PageViewModel object as its DataContext, which contains a StatusHelper property named 'Status', then you can bind to it as following:

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

The exact answer depends on how you've set up your view-model / data-context hierarchy.

Pieter Witvoet
  • 2,773
  • 1
  • 22
  • 33
  • Thanks for your reply. The panel above does not have a datacontext set currently. Also the problem is that object of the StatusHelper class is created at the page level and i am unable to figure out that how i can access that on the main window. The other option which i thought about was to use a static class and set the properties however again i am stuck while accessing the object of that class. The option which comes to my mind is to create a common control for the status bar and then use it on every page however that does not look appealing to me at this moment. – Rachit Jan 22 '14 at 11:11
  • You have a MainWindow that needs to display the content of a page as well as the status message of the current page. Then simply store a reference to the view-model of the current page in the view-model (data-context) of the MainWindow, for example as a property called CurrentPage. The binding would then be: {Binding CurrentPage.Status.Message}. Are you familiar with MVVM? – Pieter Witvoet Jan 22 '14 at 12:19
0

If you don't already have one, add a base view model class to your application. Add a class that implements the Singleton Pattern to your application so that there can only be one instance of it. Add a reference to that class to your base view model, ensuring you only access it using the Instance property:

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

Now every view model in your application has access to the properties from this class, so therefore you can data bind to them from every view:

<TextBlock Text= "{Binding StateManager.YourPropertyName}" />
Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Sheridan thanks for your answer. I got the flavor of what are you suggesting but i achived this in a different manner. I would try to do this also as this looks more neat in terms of the implementation. – Rachit Jan 23 '14 at 11:52
0

I got the answer to this question. What i did was to pass on the instance of the main page to a common helper class(which is static) in a static variable . Now Create a property on the main page which would return the instance of the status bar (sbMain). Call the status helper class from the master forms and call the update method on it.

Add property SmStatusBar to the MainWindow also passthe instance to the main Window to a class while the initilization of the main page as below

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

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

Add a static property on the Common Helper class

    public static MainWindow MainWindow { get; set; }

Now Create a class 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;
     }

}
Rachit
  • 136
  • 1
  • 7