9 Replies - 908 Views - Last Post: 21 January 2015 - 06:06 PM Rate Topic: -----

#1 Damage   User is offline

  • Lord of Schwing
  • member icon

Reputation: 300
  • View blog
  • Posts: 1,989
  • Joined: 05-June 08

Reloading a disposed object WPF

Posted 21 January 2015 - 03:13 PM

I've got a list of Message items,

Window loads, links to msmq on remote server and lists the current messages in the queue in a list box

On selected item changed, the window displays some details about the currently selected message (sent date, body etc)

This all works fine provided i only view a message once, as soon as i try view it again i get an error saying the message has been disposed. I tried catching the exception and re-calling the method, passing through the same message but my app freezes.

Is there a way to do this without reloading the whole queue?

 private void loadMessageDetails(Message currentlySelectedMessage)
        {
            string messageBody = "";
            //LOAD METADATA DETAILS
            try
            {
                lblSize.Content = "Message size is: " + currentlySelectedMessage.BodyStream.Length + " Bytes";
                lblSentDate.Content = "Message sent at: " + currentlySelectedMessage.SentTime;
                lblArrivedDate.Content = "Message arrived at: " + currentlySelectedMessage.ArrivedTime;
               
            }
            //Try reloading message object - FREEZE
            catch (System.ObjectDisposedException ode)
            { /*Message selectedQueueMessage = (Message)lstboxMessages.SelectedItem;
                loadMessageDetails(selectedQueueMessage);*/
               
            }
            catch (Exception ex)
            { MessageBox.Show(ex.Message.ToString(), ex.GetType().ToString()); }

            //READ MESSAGE BODY
            try
            {
                using (System.IO.StreamReader messageStream = new StreamReader(currentlySelectedMessage.BodyStream))
                {

                    while (messageStream.Peek() >= 0)
                    {
                        messageBody += messageStream.ReadLine();
                    }
                }
            }           
            catch (Exception ex)
            { MessageBox.Show(ex.Message.ToString(), ex.GetType().ToString()); }

            try
            {
            //txtMessageBody.Text = currentlySelectedMessage.Body.ToString();
            txtMessageBody.Text = messageBody.ToString();
            // to test output
            //writeMessageToFile(messageBody);

            //Get the work order id. using regex to match text between xml tags <tcc:Id>
            Match regExMatch = Regex.Match(messageBody, @"<tcc:Id>([A-Za-z0-9\-]+)\</tcc:Id>", RegexOptions.IgnoreCase);
            if (regExMatch.Success == true)
            { lblWOID.Content = "Work Order ID: " + regExMatch.Groups[1].Value; }
            }
              catch (Exception ex)
              { MessageBox.Show(ex.Message.ToString(), ex.GetType().ToString()); }

        }



Is This A Good Question/Topic? 0
  • +

Replies To: Reloading a disposed object WPF

#2 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6535
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Reloading a disposed object WPF

Posted 21 January 2015 - 03:35 PM

You need to stop. You have problems with your understanding of WPF.

You should NOT be doing this:
lblSize.Content = "Message size is: " + currentlySelectedMessage.BodyStream.Length + " Bytes";
	               lblSentDate.Content = "Message sent at: " + currentlySelectedMessage.SentTime;
	               lblArrivedDate.Content = "Message arrived at: " + currentlySelectedMessage.ArrivedTime;


The content of these controls should be bound to properties on your dataobject.
Do NOT do this WinForms garbage of nameing your WPF controls then directly updating them like this. So very wrong.

Read up on MVVM concepts.
Was This Post Helpful? 1
  • +
  • -

#3 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6535
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Reloading a disposed object WPF

Posted 21 January 2015 - 03:44 PM

You should have an ObservableCollection<YourMessageObjectType> that is the collection of messages.
Then you have some control, such as a ListView where these are listed (maybe just the Time and Name for example)
When you select one, the SelectedMessage property updates.
All your GUI should be bound to properties on the SelectedMessage.

At this point you don't have a LoadMessage() method at all. It just isn't needed. All your GUI will update when you change the SelectedMessage
Was This Post Helpful? 1
  • +
  • -

#4 Damage   User is offline

  • Lord of Schwing
  • member icon

Reputation: 300
  • View blog
  • Posts: 1,989
  • Joined: 05-June 08

Re: Reloading a disposed object WPF

Posted 21 January 2015 - 03:58 PM

Great thanks, yup, yeah i really have no idea of how to effectively use wpf. I get too sidetracked on trying to do stuff with that language itself and shoehorn it onto a display. I really do need to spend time on that.
Was This Post Helpful? 0
  • +
  • -

#5 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6535
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Reloading a disposed object WPF

Posted 21 January 2015 - 04:11 PM

I'm finishing up a simple binding example to post for ya. Give me a couple minutes.
Was This Post Helpful? 0
  • +
  • -

#6 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6535
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Reloading a disposed object WPF

Posted 21 January 2015 - 04:18 PM

This is a really fast hack. It is using the Mainwindow as the datasource instead of a seperate ViewModel. But it shows how the binding works, without any WinForms-esque event handlers, a collection of objects and a selected object.

Attached Image

When you click on each item in the listbox, the details update themselves. All on binding.

Mainwindow.xaml
Spoiler


Mainwindow.xaml.cs
Spoiler


MessageObj.cs
Spoiler

Was This Post Helpful? 3
  • +
  • -

#7 Damage   User is offline

  • Lord of Schwing
  • member icon

Reputation: 300
  • View blog
  • Posts: 1,989
  • Joined: 05-June 08

Re: Reloading a disposed object WPF

Posted 21 January 2015 - 05:09 PM

Thanks! Thats awesome
Was This Post Helpful? 0
  • +
  • -

#8 andrewsw   User is offline

  • never lube your breaks
  • member icon

Reputation: 6818
  • View blog
  • Posts: 28,231
  • Joined: 12-December 12

Re: Reloading a disposed object WPF

Posted 21 January 2015 - 05:19 PM

@tlhIn`toq (off topic)

Why does this area appear in grey?

Attached Image

I'm sure it's something simple I'm missing..? Here's the code:
#define RUNNING_NET45 // Put this as first line of file

using System;
using System.Collections.Generic;
using System.ComponentModel;    // INotifyPropertyChanged
using System.Diagnostics;       // DebuggerStepThrough
using System.Linq;
using System.Runtime.CompilerServices;    // .NET 4.5
using System.Text;
using System.Threading.Tasks;

namespace MultiBinding {
    public class Person : INotifyPropertyChanged {
        #region private members

        private string _FirstName;
        private string _LastName;

        #endregion

        #region public properties

        public string FirstName {
            [DebuggerStepThrough]
            get {
                return _FirstName;
            }
            [DebuggerStepThrough]
            set {
                if (_FirstName != value) {
                    _FirstName = value;
                    onpropertychanged("FirstName");
                }
            }
        }
        public string LastName {
            [DebuggerStepThrough]
            get {
                return _LastName;
            }
            [DebuggerStepThrough]
            set {
                if (_LastName != value) {
                    _LastName = value;
                    onpropertychanged("LastName");
                }
            }
        }

        #endregion

        #region INotifyPropertyChanged members

        public event PropertyChangedEventHandler PropertyChanged;
#if (RUNNING_NET45)
        //.NET 4.5 doesn't require the property to send its name.
        private void onpropertychanged([CallerMemberName] string prop = "") {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(prop));
        }

#else
        // pre .NET 4.5
        private void onpropertychanged(string propertyName) {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
#endif

        #endregion
    }
}


Was This Post Helpful? 0
  • +
  • -

#9 tlhIn`toq   User is offline

  • Xamarin Cert. Dev.
  • member icon

Reputation: 6535
  • View blog
  • Posts: 14,450
  • Joined: 02-June 10

Re: Reloading a disposed object WPF

Posted 21 January 2015 - 05:50 PM

It's called a pre-processor directive. You define a constant then you can use that to alter what blocks of code are included when the application is compiled.

Are you saying you've never included something like:

#if DEBUG
   // This this stuff when debugging
#else
   // Do this stuff in the release version
#endif


We were just talking about this in anther thread:
http://www.dreaminco...ost__p__2112585
Was This Post Helpful? 0
  • +
  • -

#10 andrewsw   User is offline

  • never lube your breaks
  • member icon

Reputation: 6818
  • View blog
  • Posts: 28,231
  • Joined: 12-December 12

Re: Reloading a disposed object WPF

Posted 21 January 2015 - 06:06 PM

I know about them :) it's been a while though..

To clarify for anyone who encounters my question, the #if or #else section will be greyed immediately according to whether RUNNING_NET45 is defined or not.

This post has been edited by andrewsw: 21 January 2015 - 06:11 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1