E_learner
E_learner

Reputation: 3582

Databinding and then calling from another class in WPF

My purpose is to add a textblock to my main UI window, of which text will be updated if needed. For that, in my UIWindow xaml I did like this:

<Window x:Class="UIDesigner.UIWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:s="clr-namespace:UIDesigner"
    xmlns:c="clr-namespace:UIDesigner.Controls"
    WindowStartupLocation="CenterScreen"        
    WindowState="Maximized"
    WindowStyle="SingleBorderWindow"
    Title="GUI"
    Height="1000" Width="1400"
    HorizontalAlignment="Center"
    VerticalAlignment="Top"
    Icon="Resources/Images/Logo.png"        
    >

<Grid Margin="0">
    <Grid Grid.Row="1" Margin="0,10,0,0">

    <GroupBox Header="Console" Grid.Column="1" Margin="0,590,0,0" HorizontalAlignment="Stretch" x:Name="consoleWindow" IsEnabled="True" VerticalAlignment="Stretch"
                >
        <TextBlock x:Name="myConsoleWindowTextBlock" Text="{Binding Path=consoleText}"/>
    </GroupBox>
    </Grid>
</Grid>

</Window>

This is the code behind:

using System.Windows;
using System.Runtime.CompilerServices;
using System.ComponentModel;

namespace UIDesigner
{
    public partial class UIWindow : Window
    {
        public UIWindow()
        {
            InitializeComponent();  
        }


        private string _consoleText;
        public string consoleText
        {
            get{ return _consoleText;}
            set
            {
                _consoleText = value;
                NotifyPropertyChanged("consoleText");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }
}

Then in my main class, I call this UIWindow like this:

namespace UIDesigner
{
    public partial class Main : Window
    {
        public Main()
        {
            InitializeComponent();
        }

    private void LoginButton_Click_1(object sender, RoutedEventArgs e)
    {        
            var myUIWindow = new UIWindow();                
            myUIWindow.PropertyChanged += new PropertyChangedEventHandler(UIWindow_PropertyChanged);

            myUIWindow.consoleText = "Hello User!";
            myUIWindow.ShowDialog();

            this.Close();

    }

    private void LoginButton_MouseEnter_1(object sender, MouseEventArgs e)
    {   
    }

    static void UIWindow_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        MessageBox.Show("Something Changed!");
        MessageBox.Show(e.PropertyName);
    }

    }

}

Now I have two problems here:

First, when my UI window starts, I indeed received two message boxes, saying "something changed" followed by "consoleText". So that means the consoleText is changed successfully. But after my UIWindow shows up, the textblock is empty, I cannot see "Hello User!" there. Seems like Text="{Binding Path=consoleText} part is not working correctly in my xaml file.

Second and most importantly, I want to change the consoleText in another different class, namely in DesignerCanvas.Commands.cs. For that I couldn't figure out any solution. I want something like this in my DesignerCanvas.Commands.cs:

namespace UIDesigner
{
    public partial class DesignerCanvas
    {

        private void changeConsoleOutput(string updatedConsoleText)
        {
            myUIWindow.consoleText = updatedConsoleText;  //obviously, this is not working
        }
    }
}

Any kind of suggestion will be much appreciated.

Upvotes: 0

Views: 1194

Answers (1)

Ashok Rathod
Ashok Rathod

Reputation: 840

1.First of two set the value in UI just add below one line

in constructor of UIWindow class

this.DataContext=this;

//because only specifying property consoletext, it will not able to know where to find consoletext.

2.u can find that UIwindow in App.Current.Windows and cast it to UIWindow type and then can access the property.

foreach(Window win in App.Current.Windows)
            {
                if (win as UIWindow != null)
                {
                    (win as UIWindow).consoletext = updatedConsoleText;
                }
            }

For second problem

Change

<TextBlock x:Name="myConsoleWindowTextBlock" Text="{Binding Path=consoleText}"/

To

<TextBlock x:Name="myConsoleWindowTextBlock" Text="{Binding Path=.}"/

and

in UIWindow constructor set

myConsoleWindowTextBlock.Datacontext=consoleText;

Upvotes: 2

Related Questions