Binding to images - wpf

I'm using a listbox with a template like the following.
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding}" Width="100" />
</DataTemplate>
</ListBox.ItemTemplate>
I bind this to an observable collection conataining 130 paths to images (all do exist, read out using System.IO.Directory) but only a few get really displayed. No exceptions that come up. Only white places where the images should be. Has anybody seen something else.
Sascha

Never seen this before but Binding is suppressing errors by default. When there are errors you can see them when you run in debug en watch in the output window of visual studio and make sure the option of the combobox "Show output from:" is set to "Debug"
Hope that this will help you to the real problem.
EDITED:
If you don't see a problem may you can find it out by hooking into the Image.ImageFailed Event. More help can be found here :
http://msdn.microsoft.com/en-us/library/system.windows.controls.image.imagefailed%28v=VS.95%29.aspx

Related

Binding DataContext in XAML With DataContext Set In Code

I have the following code:
ProcessMainWindow.xaml.cs
public ProcessMainWindow(SourceTableRowInfo rowContent)
{
InitializeComponent();
this.DataContext = rowContent;
}
ProcessMainWindow.xaml
<!--Insert Code---->
<TabItem x:Name="postProcessTab" Header="Post-Processes">
<local:PostProcessUserControl PostProcessItem="{Binding PostProcess, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</TabItem>
So RowContent has an element called PostProcess in it. I am trying to bind that element to a UserControl Dependency Property, but cannot get the binding to work. Based off what I was reading here (Using the DataContext) my understanding is that what I have should work, but I can't get it to work. So am I misunderstanding what it is saying? I have read a few other pages but still can't figure it out.
I have also tried:
<!--Insert Code---->
<TabItem x:Name="postProcessTab" Header="Post-Processes">
<local:PostProcessUserControl PostProcessItem="{Binding, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Path=PreProcess}" />
</TabItem>
If these are correct, I guess I have an error elsewhere in my code. I have yet to fully understand data binding in WPF to know if that is the case though so any help would be appreciated.
One thing to try is to put a trace on the Binding:
PostProcessItem="{Binding PostProcess, PresentationTraceSources.TraceLevel=High}.
Then look for what it tells you at runtime in the Output pane in VS. This can help you identify cases where your DataContext isn't what you think it is, or your Path is misspelled -- all the simple stuff that the compiler catches in C# but can't be detected at compile time in a late-binding/duck-typed miasma like XAML.
Don't leave those traces on bindings once you're done with them; they can really slow things down. Or at least set TraceLevel=None, to save trouble if think you'll be coming back to one later.

Xaml parser exception

This is something that's driving me crazy.. I have a WPF project which is already in production. Now, I have to make some fix for which I have to set x:Name property to couple of controls. But, when I set x:Name property for any control, it's throwing XamlParser exception (inner exception says cannot cast type XXX to type Button where XXX is type of control for which I am setting x:Name property).
It also shows an additional error like,
Additional information: Set connectionId threw an exception.
I have closed and reopened Visual Studio; I have cleaned the solution and rebuilt many times; but no use.
Can anybody let mw know what's going on?
Here is the code - I have just added x:Name = "PnlUpDown" to stack panel.
<StackPanel Name="PnlUpDown" VerticalAlignment="Center" Grid.Column="3">
<Button x:Name="BtnMoveUp" Padding="3,5" Margin="5,0,0,3" Tag="MOVEUP" >
<Polygon Points="0,15 5,0,10,15" Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType=Button}}"/>
</Button>
<Button x:Name="BtnMoveDown" Padding="3,5" Margin="5,3,0,0" Tag="MOVEDOWN" >
<Polygon Points="0,0 5,15,10,0" Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType=Button}}"/>
</Button>
</StackPanel>
Now.. I find that not only x:Name property.. It's not allowing me to set any other property to any control - In general, if I modify my XAML it's throwing error..!!!!!!! For everything it's throwing Set Connection Id error :(
First, check out this post: How do you debug a XamlParseException?. Specifically, look at the call stack as noted in the answer by Igor Zevaka.
Also check the answers to the following questions:
XamlParseException after deploying WPF project
xamlParseException on window launch
XamlParseException can be one of the more difficult exceptions to find. If none of those point you in the right direction, look at the code-behind and the data context. Perhaps there is an exception being thrown in one of those locations.
I don't know how it's related but I just restarted my machine and the issue got resolved !!!! May be Visual Studio 2013 gets refreshed when the machine reboots.. I don't know. Anyways, Thanks everyone for your replies.

Silverlight/XNA Data Binding Irregularity

I have to preface this with a disclaimer. I'm a novice programmer, I've tried solving this on my own for days but have now completely run out of ideas/blog posts/walkthroughs and other sources. I really appreciate your time in reading and potentially replying.
I am trying to integrate scoreloop into a game I'm developing but am getting some very strange results with data binding and a listbox. My tests (below) imply that there has to be something I'm doing wrong with bindings, but the crazy thing is it actually works the first time I use it, but not for subsequent levels. Here is the important code I'm using:
XAML:
<ListBox x:Name="LeftListBox" Margin="12,48,0,128" ItemsSource="{Binding}" Background="{x:Null}" HorizontalAlignment="Left" Width="240">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17">
<StackPanel Margin="0,0,0,0" Orientation="Horizontal" HorizontalAlignment="Left">
<TextBlock Text="{Binding Rank}" TextWrapping="NoWrap" />
<TextBlock Text="." Width="54"/>
<TextBlock Text="{Binding Result}" TextWrapping="NoWrap" Width="76"/>
<TextBlock Text="{Binding User.Login}" TextWrapping="NoWrap"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I have an event registered to fire whenever scores are loaded, this sets the binding and logs a debug message:
LeftListBox.DataContext = App._scoresController.Scores;
Debug.WriteLine("Scores Loaded");
App._scoresController.Scores contains User.Login, Rank, and Result.
After I beat a level it pulls down scores and displays them int he listbox just like I expect. As soon as it goes through the same cycle for the next level though the listbox is blank. The debug line of "Scores Loaded" always gets logged, so I know the event is firing.
What I've done so far in testing:
Turned on ALL for bindings logging and could not see anything getting logged in the output.
Set a break point at the Debug "Scores Loaded" line and can see that everytime it hits there it correctly assigned the datacontext,
with the correct fields with exactly matching names
Tried using Dispatcher.BeginInvoke(LoadScores); to be sure I was doing it off the UI thread in case this was somehow a threading
issue
Set the background color on the stackpanel to a color that I could use to ensure it wasn't being collapsed or hidden by another control
or a storyboard animation
Created a copy of the same listbox, set listbox.datacontext = this in the same LoadScores() method, then set up local variables
for it to bind to. Found that this exhibited the same behavior,
disappearing on the second time I go to set the datacontext
Created a copy of the listbox and removed all bindings, setting the three text fields manually. This would not disappear, but
showed up every time I beat a level
Beat one level (getting it to work), beat another (getting it to disappear), navigate away from the gamepage.xaml/gamepage.xaml.cs where the gameplay takes place (like to a mainpage.xaml, then back to the gamepage. This does not fix the problem, so I'm assuming the problem is higher up than something inside the gamepage.xaml/gamepage.xaml.cs
I feel like I've got to be doing something painfully stupid/obvious, but I'm a novice programmer, just picking pieces up as I have a need, and this is my first venture into the world of data binding.
I would greatly appreciate any suggestions.
Thanks in advance for your time.
I found the problem. I was wrong when I said I was never leaving the GamePage.xaml.cs and Gamepage.xaml.
I reveiwed my code and found that I was actually jumping out to a transition page that lists the details of the next level, then back to GamePage.
Whenever I left the page, strange things would happen to the App._scoresController.Scores. If I created a private _scoresController.Scores within GamePage.xaml.cs and used that instead of the one in App then everything works. It looks like something strange with Scoreloop.

Silverlight 4: "Invalid XAML" using Converter in DataTemplate

maybe you could help me understand why I get an unhandled exception "Invalid XAML" in Visual Studio 2010 designer when trying to do the following on a Page.
I have a Converter named DateTimeConverter that converts a date into a German date string. The converter works fine. I've included the namespace and added the following to the page's resources:
<navigation:Page.Resources>
<myClasses:DateTimeConverter x:Key="dateTime" />
</navigation:Page.Resources>
Now I have a list box that I want to bind to a list of objects. I do the binding in code, but I would like to define the data template. Thus I've added the following to my layout:
<ListBox x:Name="lbConversation" BorderBrush="#00000000">
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="0" Padding="4">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Message, Mode=OneWay}" />
<TextBlock Text="{Binding TimeStamp, Mode=OneWay, Converter={StaticResource dateTime}}" />
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And this works fine when I run. However, in the code section, the code for the data template is undercurled and the designer says "Invalid XAML". When I remove the Converter=... part, this error is gone.
Is this a designer bug? What can I do?
EDIT
By the way: The exact same code does not throw the error within a WPF project!
Just adding to this question as I found a solution.
The solution to my case was here: http://forums.silverlight.net/post/618518.aspx
Apparently you must not have a space character in your project name or assembly name. D'oh!
Hope it helps.
Sorry, can't replicate this at all, do you have some design-time data that may be the cause of the weird error?
Also, since you said that you're using the converter to output german dates... wouldn't it be easier to let the framework do this kind of things, as it probably does them a lot better? Set the entire application thread's CultureInfo to german and all formatting will be done with that culture's settings; of course it's still possible you only want some controls internationalized...
I can't see anything wrong with your Xaml however I wonder if this is a result of the language setting used when the Xaml is parsed. By default Xaml is parsed using the InvariantCulture however it would appear that the designer in visual studio parses the Xaml using the current culture. Hence at times you can get unexpected differences in behaviour at design time than you do at runtime.
In fact if you do this in the constructor of your UserControl before calling InitializeComponent:-
this.Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentCulture.Name);
You might not need your converter at all.
I came across "Invalid XAML" error when I had my converter marked internal. Change the modifier to public and everything is as expected.
Hope this help.

WP7 / Silverlight]Binding remote images in listbox so the UI doesn't block

(Scenario: Windows Phone 7 / Silverlight)
I have a ListBox that i will simplify to this XAML:
<ListBox ItemsSource="{Binding Path=ImageLinks}"> <!-- ImageLinks a collection in ViewModel -->
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Path=ImageSource}" /> <!-- ImageSource is a string with the url to the image-->
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Now, the above code works, but the problem is that as the item is rendered/loaded or whatever it starts downloading the image but while doing so, it blocks the UI. And since more than one item fits at the time, the UI gets blocked until all of the corresponding images are downloaded.
So, the question is, how do i get this functionality without the UI being blocked while downloading the images (and avoiding redownloading all of them each time the view gets navigated to)?.
Thanks in advance.
Well problem Solved, Thanks to all of you who took the time to help me.
Delay created a solution to exactly this problem.
See his blog entry on the topic at http://blogs.msdn.com/b/delay/archive/2010/09/02/keep-a-low-profile-lowprofileimageloader-helps-the-windows-phone-7-ui-thread-stay-responsive-by-loading-images-in-the-background.aspx
You could populate ImageLinks in a secondary thread that is not tied to the UI and bind it directly from the code-behind once it is populated instead of direct XAML binding.
You could also use the PersistentImageCache class from my Kawagoe toolkit, which has been designed precisely for this use case. Let me know if it helps! :)

Resources