Author Topic: Programming Advice  (Read 10254 times)

0 Members and 1 Guest are viewing this topic.

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11658
  • Thanked: 20379 times
Re: Programming Advice
« Reply #60 on: October 25, 2010, 09:06:36 AM »
There is a Refresh method for the listbox. I am using that to force a data update when I change the datasource. For example:

            lstFleet.ItemsSource = RaceFleets;
            lstFleet.Items.Refresh();

Steve
 

Offline ndkid

  • Warrant Officer, Class 1
  • *****
  • n
  • Posts: 86
  • Thanked: 4 times
Re: Programming Advice
« Reply #61 on: October 25, 2010, 09:26:52 AM »
Welcome to today's edition of Steve's Programming Problems...

I have a listbox (lstSystems) bound to a collection of System objects (Galaxy.SystemList). The ToString for System has been overidden to return the System Name. Everything works fine and the listbox displays a list of system names. I would like to sort the systems alphabetically in the listbox. The Items property of the listbox has a collection of SortDescription objects, which is empty at runtime. Therefore I am using the following code snippet to try and sort the listbox on SystemName.

            lstSystems.ItemsSource = Galaxy.SystemList;
            lstSystems.Items.SortDescriptions.Add(new SortDescription("SystemName", ListSortDirection.Ascending));

The sort order does change after the second line is executed and it always changes in the same way, but it certainly isn't anything to do with system name. In fact, despite the fact the sort always happens in the same way I can find no rational explanation for the order of the systems. Any ideas? Am I missing something obvious?

Looking at the MSDN reference for SortDescriptions and the SortDescription class (I've never used it before, myself), I get the impression that the properties one can refer to are those of the ListBoxItem, not those of the object referenced by the list box item. If you try:

Code: [Select]
            lstSystems.Items.SortDescriptions.Add(new SortDescription("Content", ListSortDirection.Ascending));

does that do what you want?
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11658
  • Thanked: 20379 times
Re: Programming Advice
« Reply #62 on: October 25, 2010, 03:20:18 PM »
Looking at the MSDN reference for SortDescriptions and the SortDescription class (I've never used it before, myself), I get the impression that the properties one can refer to are those of the ListBoxItem, not those of the object referenced by the list box item. If you try:

Code: [Select]
            lstSystems.Items.SortDescriptions.Add(new SortDescription("Content", ListSortDirection.Ascending));

does that do what you want?

I haven't tried it yet but that looks like the same type of misunderstanding I had with listboxes. Trying to use a specific rather than generic reference.

Steve
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11658
  • Thanked: 20379 times
Re: Programming Advice
« Reply #63 on: October 25, 2010, 03:23:08 PM »
And now a simple yet incredibly frustrating problem. All I want to do is add an image to a button. In VB6 this takes about 5 seconds. In C#/WPF it seems to involved creating a resource within the project and then assigning that resource. I cannot get this to work though and I have been trying for about two hours :). Everytime I try to specify an image within XAML I get an error that I am trying to set content twice and I have no idea why. Could anyone provide a very simple example of how to do this?

Steve
 

Offline ndkid

  • Warrant Officer, Class 1
  • *****
  • n
  • Posts: 86
  • Thanked: 4 times
Re: Programming Advice
« Reply #64 on: October 25, 2010, 03:33:35 PM »
And now a simple yet incredibly frustrating problem. All I want to do is add an image to a button. In VB6 this takes about 5 seconds. In C#/WPF it seems to involved creating a resource within the project and then assigning that resource. I cannot get this to work though and I have been trying for about two hours :). Everytime I try to specify an image within XAML I get an error that I am trying to set content twice and I have no idea why. Could anyone provide a very simple example of how to do this?

I'll quote from http://www.switchonthecode.com/tutorials/creating-buttons-with-xaml-and-csharp:

All that is required to put an image in a button is to add an Image tag inside the Button tag.
Code: [Select]
<Button Name="myButton" Width="75" Height="23" Margin="10,10"
   VerticalAlignment="Bottom" HorizontalAlignment="Right" FontWeight="bold"
   Background="LightBlue" BorderBrush="DarkBlue" Foreground="DarkBlue">
  <Image Source="F:\Images\myImage.png" />
</Button>
You may have noticed that I removed the Content attribute. That's because the Image tag also counts as content. A button can only have the content set once. If you were to leave the the Content attribute and add the Image tag, you would get the following error: "The property 'Content' is set more than once."

And from http://www.vistax64.com/avalon/10390-button-image-not-showing-xaml.html:
In WPF, images must be embedded as Resource - type items. This is different from the WinForms way to use the Resources.resx.
I usually create a folder, say 'Images' in my project - this creates a file folder with the same name on disk, then copy the image(s) into this folder (using windows explorer). Then, go back to Visual Studio. In the project view, right-click on the 'Images' folder and choose 'Add Existing Item' to add the image as a resource (shows as Build Action : Resource in the properties window).
Then simply use e.g. Image Source="Images/mypicture.jpg" im XAML and it should work.
« Last Edit: October 25, 2010, 03:35:06 PM by ndkid »
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11658
  • Thanked: 20379 times
Re: Programming Advice
« Reply #65 on: October 25, 2010, 03:47:09 PM »
I'll quote from http://www.switchonthecode.com/tutorials/creating-buttons-with-xaml-and-csharp:

All that is required to put an image in a button is to add an Image tag inside the Button tag.
Code: [Select]
<Button Name="myButton" Width="75" Height="23" Margin="10,10"
   VerticalAlignment="Bottom" HorizontalAlignment="Right" FontWeight="bold"
   Background="LightBlue" BorderBrush="DarkBlue" Foreground="DarkBlue">
  <Image Source="F:\Images\myImage.png" />
</Button>
You may have noticed that I removed the Content attribute. That's because the Image tag also counts as content. A button can only have the content set once. If you were to leave the the Content attribute and add the Image tag, you would get the following error: "The property 'Content' is set more than once."

And from http://www.vistax64.com/avalon/10390-button-image-not-showing-xaml.html:
In WPF, images must be embedded as Resource - type items. This is different from the WinForms way to use the Resources.resx.
I usually create a folder, say 'Images' in my project - this creates a file folder with the same name on disk, then copy the image(s) into this folder (using windows explorer). Then, go back to Visual Studio. In the project view, right-click on the 'Images' folder and choose 'Add Existing Item' to add the image as a resource (shows as Build Action : Resource in the properties window).
Then simply use e.g. Image Source="Images/mypicture.jpg" im XAML and it should work.

Aha! Thankyou!

Now I get a GIF file to appear, although the button is HUGE, but for some reason it won't load a .ICO file. There is no error and the button is a tiny dot (as I haven't specified a size). Do you know if .ICO files are not acceptable for buttons?

Steve
« Last Edit: October 25, 2010, 04:15:41 PM by Steve Walmsley »
 

Offline ndkid

  • Warrant Officer, Class 1
  • *****
  • n
  • Posts: 86
  • Thanked: 4 times
Re: Programming Advice
« Reply #66 on: October 26, 2010, 09:19:37 AM »
Aha! Thankyou!

Now I get a GIF file to appear, although the button is HUGE, but for some reason it won't load a .ICO file. There is no error and the button is a tiny dot (as I haven't specified a size). Do you know if .ICO files are not acceptable for buttons?

If the image starts at the wrong resolution for you, you can probably load it into an image object and resize it. Or you may be able to resize the image as part of the button... I'd have to dig to find out.

I've found one mention of icons on buttons:
http://www.codeproject.com/Messages/1649315/Re-How-to-use-ico-files-in-toolbar-buttons-etc.aspx
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11658
  • Thanked: 20379 times
Re: Programming Advice
« Reply #67 on: October 26, 2010, 11:21:40 AM »
If the image starts at the wrong resolution for you, you can probably load it into an image object and resize it. Or you may be able to resize the image as part of the button... I'd have to dig to find out.

I've found one mention of icons on buttons:,
http://www.codeproject.com/Messages/1649315/Re-How-to-use-ico-files-in-toolbar-buttons-etc.aspx

I managed to sort it out. One of the major advantages of WPF is that you don't have to specify sizes for controls. The disadvantage of that is the buttons will expand to fit the image. By specifying a size for the button, the image shrinks to fit. So I now have buttons with images working fine. Thanks for the help!

Steve
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11658
  • Thanked: 20379 times
Re: Programming Advice
« Reply #68 on: October 27, 2010, 08:18:26 AM »
Today's problem is the weirdest so far...

I have some ship graphics listed under Images in the project resource list. I load these at start-up into Image objects so I can access them easily while the program is running and I won't have to load each graphic multiple times. Each time I add some new graphics to the resource list, there are no errors when they load and no errors when I assign the source property of a newly created image to their source property. However, the newly created image is blank on the screen. Then, after a while they will suddenly start working with no apparent reason and no code change. So I add more graphics and they don't work at first. After some time, ranging from a few minutes to a few hours they will start working too.

There must be some sort of refresh happening somewhere in Visual Studio but I have no idea how to manually trigger it. Even quitting and restarting VS doesn't change anything. It's definitely the image rather than the in-game objects because I have tried assigning new images to objects that are aready working, without success (for a while anyway).

The relevant lines of code are:

            // On startup
            imgWarshipFriendly = new Image();
            imgWarshipFriendly.Source = new BitmapImage(new Uri("Images/NavalIcons/WarshipFriendly.png", UriKind.Relative));

            // run-time - only start working after the new resources have been in the project for a while
            image1.Source = imgWarshipFriendly .Source;

Steve
« Last Edit: October 27, 2010, 08:21:18 AM by Steve Walmsley »
 

Offline ndkid

  • Warrant Officer, Class 1
  • *****
  • n
  • Posts: 86
  • Thanked: 4 times
Re: Programming Advice
« Reply #69 on: October 27, 2010, 09:27:18 AM »
I have some ship graphics listed under Images in the project resource list. I load these at start-up into Image objects so I can access them easily while the program is running and I won't have to load each graphic multiple times. Each time I add some new graphics to the resource list, there are no errors when they load and no errors when I assign the source property of a newly created image to their source property. However, the newly created image is blank on the screen. Then, after a while they will suddenly start working with no apparent reason and no code change. So I add more graphics and they don't work at first. After some time, ranging from a few minutes to a few hours they will start working too.

There must be some sort of refresh happening somewhere in Visual Studio but I have no idea how to manually trigger it. Even quitting and restarting VS doesn't change anything. It's definitely the image rather than the in-game objects because I have tried assigning new images to objects that are aready working, without success (for a while anyway).

Looking at:
http://msdn.microsoft.com/en-us/library/ms748873.aspx#_displayingimages

and:

http://msdn.microsoft.com/en-us/library/system.windows.controls.image.aspx

I get the impression that you may be conflating the use of BitmapImage and Image. I believe Image is a control that takes as its source a BitmapImage. So it seems like what you probably want to do is load the images into BitmapImage objects and then, as necessary, display them via Image objects.

Here's a discussion that seems like it's aiming for behavior similar to yours:
http://stackoverflow.com/questions/347614/wpf-image-resources

If your display desires get quirky, I may eventually have to suggest you consider using XNA or DirectX, instead of basic WPF stuff. ;-)
 

Offline Steve Walmsley (OP)

  • Aurora Designer
  • Star Marshal
  • S
  • Posts: 11658
  • Thanked: 20379 times
Re: Programming Advice
« Reply #70 on: October 27, 2010, 09:41:31 AM »
Looking at:
http://msdn.microsoft.com/en-us/library/ms748873.aspx#_displayingimages

and:

http://msdn.microsoft.com/en-us/library/system.windows.controls.image.aspx

I get the impression that you may be conflating the use of BitmapImage and Image. I believe Image is a control that takes as its source a BitmapImage. So it seems like what you probably want to do is load the images into BitmapImage objects and then, as necessary, display them via Image objects.

Here's a discussion that seems like it's aiming for behavior similar to yours:
http://stackoverflow.com/questions/347614/wpf-image-resources

If your display desires get quirky, I may eventually have to suggest you consider using XNA or DirectX, instead of basic WPF stuff. ;-)

The problem isn't that the code doesn't work, just that it doesn't work for about an hour. If I walk away for an hour and come back, its working and always works after that point. I am wondering why it doesn't work immediately. The code above loads the PNG file into a BitmapImage and then assigns that BitmapImage to the source property of an Image - I am just doing it in one line of code. I got the actual code from MSDN.

Steve
 

Offline ndkid

  • Warrant Officer, Class 1
  • *****
  • n
  • Posts: 86
  • Thanked: 4 times
Re: Programming Advice
« Reply #71 on: October 27, 2010, 09:59:52 AM »
The problem isn't that the code doesn't work, just that it doesn't work for about an hour. If I walk away for an hour and come back, its working and always works after that point. I am wondering why it doesn't work immediately. The code above loads the PNG file into a BitmapImage and then assigns that BitmapImage to the source property of an Image - I am just doing it in one line of code. I got the actual code from MSDN.

Oh, sorry, misread.

Let's see... I don't have a quick and easy answer, so let's try and confirm the root problem. BitmapImage objects have a downloadcomplete event handler. How about creating a function to handle that event, so you can see whether it's being thrown before you attach the bitmapimage to the image? If you're hitting that, then the slowdown is probably in the image object; if you're not, the slowdown is in the bitmapimage object, and I'll better know where to look for ideas.