Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. WPF
  4. Two-way binding problem

Two-way binding problem

Scheduled Pinned Locked Moved WPF
wpfhelpcsharpwcfcom
9 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    Ravadre
    wrote on last edited by
    #1

    Hi, Recently I'm trying to learn WPF, and I've stumbled across a problem, I can solve it, but I'm not happy with the result code, so maybe someone could help me to polish it a bit. Let's say, I have class XManager, that manages classes X, also, it has reference to currently active X instance, each class X has it's own Text property, I want to do a two way binding between textbox and this text property. It looks like this:

    class XManager
    {
    private X activeX;

    public X ActiveX
    {
    get { return activeX; }
    }
    }

    class X : INotifyPropertyChanged
    {
    public string Text { get; set; }

    public void PutSomeTextProgramatically(string someText)
    {
    Text += someText;
    if (PropertyChanged != null)
    PropertyChanged(this, new PropertyChangedEventArgs("Text"));
    }
    }

    Now, I do have a manager accessible from XAML:

    <Windows.Resources>
    <local:XManager x:Key="xManager"/>
    </Windows.Resources>

    My binding to it looks like this:

    <TextBox Name="someBox">
    <TextBox.Text>
    <Binding Mode="TwoWay" Source="{StaticResource xManager}" Path="ActiveX.Text" />
    </TextBox.Text>
    </TextBox>

    Such code won't work properly, because we've binded to XManager's "ActiveX.Text", but we never change it, so workaroun I did was to add do my manager such code:

    //This one is invoked when activeSession signals PropChange
    void XSession_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
    if (e.PropertyName == "Text")
    {
    if (PropertyChanged != null)
    PropertyChanged(this, new PropertyChangedEventArgs("ActiveSession.Text"));
    }
    }

    Now it will work, but I find such code a bit ugly, I'd like to bind "directly" to PropertyChange event inside XSession, not to some sort of a wrapper. Is this possible, or maybe I don't see something obvious?

    L 1 Reply Last reply
    0
    • R Ravadre

      Hi, Recently I'm trying to learn WPF, and I've stumbled across a problem, I can solve it, but I'm not happy with the result code, so maybe someone could help me to polish it a bit. Let's say, I have class XManager, that manages classes X, also, it has reference to currently active X instance, each class X has it's own Text property, I want to do a two way binding between textbox and this text property. It looks like this:

      class XManager
      {
      private X activeX;

      public X ActiveX
      {
      get { return activeX; }
      }
      }

      class X : INotifyPropertyChanged
      {
      public string Text { get; set; }

      public void PutSomeTextProgramatically(string someText)
      {
      Text += someText;
      if (PropertyChanged != null)
      PropertyChanged(this, new PropertyChangedEventArgs("Text"));
      }
      }

      Now, I do have a manager accessible from XAML:

      <Windows.Resources>
      <local:XManager x:Key="xManager"/>
      </Windows.Resources>

      My binding to it looks like this:

      <TextBox Name="someBox">
      <TextBox.Text>
      <Binding Mode="TwoWay" Source="{StaticResource xManager}" Path="ActiveX.Text" />
      </TextBox.Text>
      </TextBox>

      Such code won't work properly, because we've binded to XManager's "ActiveX.Text", but we never change it, so workaroun I did was to add do my manager such code:

      //This one is invoked when activeSession signals PropChange
      void XSession_PropertyChanged(object sender, PropertyChangedEventArgs e)
      {
      if (e.PropertyName == "Text")
      {
      if (PropertyChanged != null)
      PropertyChanged(this, new PropertyChangedEventArgs("ActiveSession.Text"));
      }
      }

      Now it will work, but I find such code a bit ugly, I'd like to bind "directly" to PropertyChange event inside XSession, not to some sort of a wrapper. Is this possible, or maybe I don't see something obvious?

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      The Path "ActiveX.Text" should be "Text" Change to: <Binding Mode="TwoWay" Source="{StaticResource xManager}" Path=".Text" /> BTW: Any reason you're not setting the DataContext on the TextBoxes Parent container to an instance of the xManager class? Then you don't need a resource. Your application may need to follow the pattern you've described, just want me sure you knew there are other ways. Also, xManager is not public. I've run into problems when the classes exposed on the UI are not public. Not all cases, just mentioning I've hit issues.

      Cheers, Karl » CodeProject 2008 MVP, CodeProject 2009 MVP My Blog | Mole's Home Page | XAML Power Toys Home Page

      Just a grain of sand on the worlds beaches.

      R 1 Reply Last reply
      0
      • L Lost User

        The Path "ActiveX.Text" should be "Text" Change to: <Binding Mode="TwoWay" Source="{StaticResource xManager}" Path=".Text" /> BTW: Any reason you're not setting the DataContext on the TextBoxes Parent container to an instance of the xManager class? Then you don't need a resource. Your application may need to follow the pattern you've described, just want me sure you knew there are other ways. Also, xManager is not public. I've run into problems when the classes exposed on the UI are not public. Not all cases, just mentioning I've hit issues.

        Cheers, Karl » CodeProject 2008 MVP, CodeProject 2009 MVP My Blog | Mole's Home Page | XAML Power Toys Home Page

        Just a grain of sand on the worlds beaches.

        R Offline
        R Offline
        Ravadre
        wrote on last edited by
        #3

        Karl Shifflett wrote:

        The Path "ActiveX.Text" should be "Text" Change to: <Binding Mode="TwoWay" Source="{StaticResource xManager}" Path=".Text" />

        I've actually did, just forgot to include this change in my post :), actually, I've manage to make it work without this wrapper thing on XManager. If I would set Path="Text", I'd have to include this wrapper, so XManager would have to catch it's activeX text change and repost it, but now for some reason I am able to set two way binding without this wrapper, just binding to Path="ActiveX.Text" (it did not work earlier heh).

        Karl Shifflett wrote:

        BTW: Any reason you're not setting the DataContext on the TextBoxes Parent container to an instance of the xManager class? Then you don't need a resource. Your application may need to follow the pattern you've described, just want me sure you knew there are other ways.

        This may be a newbie question, but how I do that? If I won't add the XManager to window resources, but only create it's instance in the code part, I don't see any of binding to it, I was actually thinking is it possible to bind to an instance of a class that was created in code, but I gave up and just used resources.

        L 1 Reply Last reply
        0
        • R Ravadre

          Karl Shifflett wrote:

          The Path "ActiveX.Text" should be "Text" Change to: <Binding Mode="TwoWay" Source="{StaticResource xManager}" Path=".Text" />

          I've actually did, just forgot to include this change in my post :), actually, I've manage to make it work without this wrapper thing on XManager. If I would set Path="Text", I'd have to include this wrapper, so XManager would have to catch it's activeX text change and repost it, but now for some reason I am able to set two way binding without this wrapper, just binding to Path="ActiveX.Text" (it did not work earlier heh).

          Karl Shifflett wrote:

          BTW: Any reason you're not setting the DataContext on the TextBoxes Parent container to an instance of the xManager class? Then you don't need a resource. Your application may need to follow the pattern you've described, just want me sure you knew there are other ways.

          This may be a newbie question, but how I do that? If I won't add the XManager to window resources, but only create it's instance in the code part, I don't see any of binding to it, I was actually thinking is it possible to bind to an instance of a class that was created in code, but I gave up and just used resources.

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          DataContext is KEY to programming in WPF. Without a full understand of this property you will struggle with WPF when infact it's super powerful and simple (once you grasp how it works.) Strongly recommend you read, print, study, this post: http://msdn.microsoft.com/en-us/library/ms752347.aspx[^] It's some VERY good Microsoft documentation on Data Binding. Another fantasic WPF Data Binding resource is: http://bea.stollnitz.com/blog/[^]

          Cheers, Karl » CodeProject 2008 MVP, CodeProject 2009 MVP My Blog | Mole's Home Page | XAML Power Toys Home Page

          Just a grain of sand on the worlds beaches.

          R 1 Reply Last reply
          0
          • L Lost User

            DataContext is KEY to programming in WPF. Without a full understand of this property you will struggle with WPF when infact it's super powerful and simple (once you grasp how it works.) Strongly recommend you read, print, study, this post: http://msdn.microsoft.com/en-us/library/ms752347.aspx[^] It's some VERY good Microsoft documentation on Data Binding. Another fantasic WPF Data Binding resource is: http://bea.stollnitz.com/blog/[^]

            Cheers, Karl » CodeProject 2008 MVP, CodeProject 2009 MVP My Blog | Mole's Home Page | XAML Power Toys Home Page

            Just a grain of sand on the worlds beaches.

            R Offline
            R Offline
            Ravadre
            wrote on last edited by
            #5

            I do get your point, I just don't see why I can't use XManager as a resource, and how else I can refer to it's instance, if I won't declare it this way? I'm using Data contexts with success while referring to resources, using DataContext="{Binding Source={StaticResource resourceKeyName}}"

            L 1 Reply Last reply
            0
            • R Ravadre

              I do get your point, I just don't see why I can't use XManager as a resource, and how else I can refer to it's instance, if I won't declare it this way? I'm using Data contexts with success while referring to resources, using DataContext="{Binding Source={StaticResource resourceKeyName}}"

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              Not sure I understand the question or what is not working as expected. I do have another consideration. When you create xManager as a resource, it is actually instantiating an instance of the xManager. So... that instance will be available to your UI but not the code-behind unless you reference the instance using resource lookup. Hope this helps.

              Cheers, Karl » CodeProject 2008 MVP, CodeProject 2009 MVP My Blog | Mole's Home Page | XAML Power Toys Home Page

              Just a grain of sand on the worlds beaches.

              R 1 Reply Last reply
              0
              • L Lost User

                Not sure I understand the question or what is not working as expected. I do have another consideration. When you create xManager as a resource, it is actually instantiating an instance of the xManager. So... that instance will be available to your UI but not the code-behind unless you reference the instance using resource lookup. Hope this helps.

                Cheers, Karl » CodeProject 2008 MVP, CodeProject 2009 MVP My Blog | Mole's Home Page | XAML Power Toys Home Page

                Just a grain of sand on the worlds beaches.

                R Offline
                R Offline
                Ravadre
                wrote on last edited by
                #7

                I think we need a 'reset', cause I'm a bit lost in our discussion as well :). So: 1. Not, I do not have any problems with code not working, I'm just referring to your statement, that I could throw out XManager from resources. 2. Let's consider such code (pseudo-xaml):

                <Window>
                <Window.Resources>
                <local:XManager x:Key="xManager"/>
                </Window.Resources>
                <Grid DataContext="{Binding Source={StaticResource xManager}}">
                ...
                <TextBox Text="{Binding Mode=TwoWay, Path=ActiveSession.InputText}" />
                </Grid>
                </Window>

                This is a simplified situation of what I have right now in my code. Referring to your post, I could throw out xManager from resources -> this implies that I create instance of the XManager in the code, fe. in the Window ctor; my question is then, how I could refer to such an instance in XAML in DataContext, and if it's not easy / possible, what's the advantage of throwing out xManager from resources. Also, inside a code I did something like this:

                XManager xMgr;
                public MainWindow()
                {
                InitializeComponent();
                xMgr = (XManager)FindResource("xManager");

                So basically, I do have a straightforward access to this instance from a code.

                L 1 Reply Last reply
                0
                • R Ravadre

                  I think we need a 'reset', cause I'm a bit lost in our discussion as well :). So: 1. Not, I do not have any problems with code not working, I'm just referring to your statement, that I could throw out XManager from resources. 2. Let's consider such code (pseudo-xaml):

                  <Window>
                  <Window.Resources>
                  <local:XManager x:Key="xManager"/>
                  </Window.Resources>
                  <Grid DataContext="{Binding Source={StaticResource xManager}}">
                  ...
                  <TextBox Text="{Binding Mode=TwoWay, Path=ActiveSession.InputText}" />
                  </Grid>
                  </Window>

                  This is a simplified situation of what I have right now in my code. Referring to your post, I could throw out xManager from resources -> this implies that I create instance of the XManager in the code, fe. in the Window ctor; my question is then, how I could refer to such an instance in XAML in DataContext, and if it's not easy / possible, what's the advantage of throwing out xManager from resources. Also, inside a code I did something like this:

                  XManager xMgr;
                  public MainWindow()
                  {
                  InitializeComponent();
                  xMgr = (XManager)FindResource("xManager");

                  So basically, I do have a straightforward access to this instance from a code.

                  L Offline
                  L Offline
                  Lost User
                  wrote on last edited by
                  #8

                  Loose the resource and all references to it. Loose the Grid DataContext XAML. In code (ctor or Loaded Event) set Window DataContext. this.DataContext = new xManager;

                  Cheers, Karl » CodeProject 2008 MVP, CodeProject 2009 MVP My Blog | Mole's Home Page | XAML Power Toys Home Page

                  Just a grain of sand on the worlds beaches.

                  R 1 Reply Last reply
                  0
                  • L Lost User

                    Loose the resource and all references to it. Loose the Grid DataContext XAML. In code (ctor or Loaded Event) set Window DataContext. this.DataContext = new xManager;

                    Cheers, Karl » CodeProject 2008 MVP, CodeProject 2009 MVP My Blog | Mole's Home Page | XAML Power Toys Home Page

                    Just a grain of sand on the worlds beaches.

                    R Offline
                    R Offline
                    Ravadre
                    wrote on last edited by
                    #9

                    Working great, I think I've tried to over-Xaml heh :). I can see how this can be useful, altough not in every situation, but still, works fine. Thank you very much for the support.

                    1 Reply Last reply
                    0
                    Reply
                    • Reply as topic
                    Log in to reply
                    • Oldest to Newest
                    • Newest to Oldest
                    • Most Votes


                    • Login

                    • Don't have an account? Register

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • World
                    • Users
                    • Groups