XamlParseException when databinding a ComboBox to a statically-defined array in XAML - wpf

I've been trying to solve this problem for over an hour now, and can't figure it out. Hopefully someone can see what I'm doing wrong.
I have two separate projects, both of which populate a combobox with an array of Doubles in the UserControl.Resources section, then databind to it in the GUI. What I'm doing is essentially just this, which works fine in kaxaml and in one of my two projects.
<Page>
<Page.Resources>
<x:Array x:Key="Increments" Type="sys:Double">
<sys:Double>0.01</sys:Double>
<sys:Double>0.02</sys:Double>
<sys:Double>0.03</sys:Double>
<sys:Double>0.04</sys:Double>
</x:Array>
</Page.Resources>
<Grid>
<ComboBox ItemsSource="{StaticResource Increments}" />
</Grid>
</Page>
The other project gives me the following error:
Cannot convert the value in attribute
'ItemsSource' to object of type
'System.Collections.IEnumerable'.
'System.Windows.Markup.ArrayExtension'
is not a valid value for property
'ItemsSource'. Error at object
'System.Windows.Controls.ComboBox' in
markup file ...
I cannot figure out why this is happening. I've tried looking at the schemas referenced in both XAML files, but they are the same... I don't have any errors or messages in the Output window. I got desperate and ran it through FxCop to see if it would catch something related, and although it has caught several valid errors, none of them were related.

I had to wrap this in an ObjectDataProvider to get it to work, and replace the StaticResource with a binding to the StaticResource:
<!-- Resources -->
<ObjectDataProvider x:Key="Incs2">
<ObjectDataProvider.ObjectInstance>
<x:Array Type="sys:Double">
<sys:Double>0.01</sys:Double>
<sys:Double>0.02</sys:Double>
<sys:Double>0.03</sys:Double>
<sys:Double>0.04</sys:Double>
</x:Array>
</ObjectDataProvider.ObjectInstance>
</ObjectDataProvider>
<!-- Page content -->
<ComboBox ItemsSource="{Binding Source={StaticResource Incs2}}" />
EDIT: I've also found that if I move the x:Array resource to the top of my Resources section, before any other resource declaration, I can use your original ItemsSource="{StaticResource ...}" and I no longer get the exception (or need the ObjectDataProvider). This would seem to be a bug in WPF.

Related

Problems adding an ObjectDataProvider in resources

I'm setting up some things in XAML, but for some reason, I'm having an issue. I'm trying to add an ObjectDataProvider to my resources, but when I'm doing that, I get this warning on my resourcedictionnary saying i cannot have multiple items in a resourcedictionnary if they don't all have key attribute in it. So I add a key to resourcedictionnary, but then I have a problem on my dynamic resource in my contentcontrol. It says it cannot resolve "DefaultEmptyPane". Then I add a reference to the key of the resourcedictionnary, but then there's some kinda of mismatch.
Is there anyone who's seeing the issue here?
Below is the XAML:
<Page.Resources>
<!--<ObjectDataProvider x:Key="projectList" MethodName=""/>-->
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Panes/DefaultEmptyPane.xaml" />
</ResourceDictionary.MergedDictionaries>
<local:PopulationNameGetNameOnlyConverter x:Key="PopulationNameGetNameOnlyConverter"/>
<local:PopulationNameGetNumberOfTestsConverter x:Key="PopulationNameGetNumberOfTestsConverter"/>
<local:PopulationNameGetDateConverter x:Key="PopulationNameGetDateConverter"/>
<local:NormValidationValueToVisibilityConverter x:Key="NormValidationValueToVisibilityConverter"/>
<local:NormrequestCalculatedToVisibilityConverter x:Key="NormrequestCalculatedToVisibilityConverter"/>
<local:RemoveUnderscoreConverter x:Key="RemoveUnderscoreConverter"/>
</ResourceDictionary>
</Page.Resources>
<ContentControl Template="{DynamicResource DefaultEmptyPane}">
<!--Content-->
</ContentControl>
Jerry, the answer lies in your XAML itself. Did u observe why it gives error for ObjectDataProvider and not for RemoveUnderscoreConverter or NormrequestCalculatedToVisibilityConverter or PopulationNameGetDateConverter etc.?
Observe their placement. They are placed inside the ResourceDictionary tag butObjectDataProvider is outside it.
Hope that helps.

Is it Possible to apply a DataTemplate to a Page?

I'm trying to follow the MVVM pattern laid out here: http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090097 I have this in my MainWindowResources.xaml file:
<DataTemplate DataType="{x:Type vm:VendorsViewModel}">
<vw:Vendors/> <--- I get a "Can't put a page in a style" error in blend with this
</DataTemplate>
and I've got this in my MainWindow.xaml file
<Window.Resources>
<ResourceDictionary Source="MainWindowResources.xaml"/>
</Window.Resources>
The mainWindow.xaml file contains a menu on the left and page holder on the right. Can I apply a dataTemplate to a <Page>? Or does it have to be a <UserControl>? As it stands, nothing is being data bound, here's what I have on the page that I want to have the viewmodel applied to:
<Custom:DataGrid Margin="0,30,0,0" d:LayoutOverrides="Width" ItemsSource="{Binding Path=AllVendors, Mode=Default}" >
<Custom:DataGrid.Columns>
<Custom:DataGridTextColumn Header="Company Name" Binding="{Binding Path=Name}" />
</Custom:DataGrid.Columns>
</Custom:DataGrid>
DataTemplates are applied to Content, which in most cases is either the Content property of a ContentControl or the Items/ItemsSource property of an ItemsControl. Page is not derived from ContentControl (UserControl is) so a DataTemplate can't be applied to its Content.
From what you're doing here it doesn't sound like that's what you're trying to do though. It looks like you're trying to use a Page in a DataTemplate which is what the error is telling you. Page is treated like Window in that it is a root container that is intended to have visual Content defined in a xaml file. UserControl has a similar purpose but can be inserted anywhere into a layout. If you change vw:Vendors to be a UserControl that should get rid of this specific error but you should also consider whether you're gaining anything from having the UserControl instead of just putting its content directly into the DataTemplate - this can help discourage code-behind and force you to use your ViewModel correctly.

WPF Databinding to Custom Collection Objects

Public Sub New(ByVal log As Entities.LogSystem)
InitializeComponent()
Me.DataContext = log
End Sub
This is the the initializer for my custom control It passes in a single entity that has several property fields. This control is added to a parent control so that it appears in a stackpanel.
Anyway I am trying to get the specific data from this control into several different text boxes:
<UserControl x:Class="LogSystemPickerItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WavelengthIS.WISRED.UserControls"
Width="579" Height="122">
<UserControl.Resources>
<local:LogSystemPickerItem x:Key="Log"/>
</UserControl.Resources>
<Grid DataContext="{Binding Source={StaticResource Log}}">
<Label Height="30" Name="Label1" VerticalAlignment="Top" Content="{Binding deptDescription}"/>
</Grid>
</UserControl>
As you can see i havent really gotten too far. I have tried many different ways to do this including using dependency properties...I just really cant find a tutorial that shows this specific circumstance...can anyone point me in the right direction?
If you're setting the DataContext in the code behind as per your first code snippet, there's no need to also do it in the XAML, so you can remove the "Log" resource and the corresponding DataContext assignment on the Grid.
Once you've done that, it should work assuming there is a deptDescription property on your log class.
... and in XAML you may do it this way...
<UserControl.DataContext>
<local:LogSystemPickerItem/>
</UserControl.DataContext>

Reference Access database dataset.designer file in WPF?

Hey, I've included an MS Access database in my WPF VB app, and I'm trying to link the data to an XCEED Datagrid. I have the following code in my testerDataSet.Designer.vb file which I assume is the funcion I should be referencing
Public ReadOnly Property Contact() As ContactDataTable
Get
Return Me.tableContact
End Get
End Property
I'm trying to get it to fill my datagirid using this
<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvs_contacts" Source="{Binding Path=Contact, *Source={x:Static testerDataSet}*}"/>
</Grid.Resources>
<xcdg:DataGridControl Margin="54,18,4,3" Name="DataGridControl1" ItemsSource="{Binding Source={StaticResource cvs_contacts}}"/>
Unfortunately the bolded/stared part is givi ng me errors, does anyone know the correct code i should be using here to reference my source?
Thanks guys!
EDIT: Okay let me try and outline what I've done... I've added an Access 2007 Database called "tester" to my project as an existing item, and VS has gone and made testerDataSet for me, and inside testerDataset.Designer.vb I assume the first code above is the code i need to display my table data.
Basically my entire code for Window1.xaml is as follows (its just a test project to see If I can actually get the database working)
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="369" Width="503" xmlns:xcdg="http://schemas.xceed.com/wpf/xaml/datagrid">
<Grid>
<Grid.Resources>
<xcdg:DataGridCollectionViewSource x:Key="cvs_contacts" Source="{Binding Path=Contact, Source={StaticResource testerDataSet}}"/>
</Grid.Resources>
<xcdg:DataGridControl Margin="54,18,4,3" Name="DataGridControl1" ItemsSource="{Binding Source={StaticResource cvs_contacts}}"/>
</Grid>
What I'm trying to achieve is for the datagrid to display the data in the Contact datatable. I'm probably missing something important here (I'm quite new to coding =/ ) To be perfectly honest I've had a hard time finding appropriate tutorials for this so I'm not entirely sure what I'm doing
THanks again
Can you update your sample to include the code for the static resource testerDataSet?
One way you can try and work around this problem is to set the Binding directly in imperative code.
DataGridControl1.DataContext = testerDataSet.Contact
Then you could modify your WPF code to be the following
<xcdg:DataGridControl
Margin="54,18,4,3"
Name="DataGridControl1"
ItemsSource="{Binding}" />
That may not be 100% what you're looking for but it should at least temporarily unblock you.

Why is my typed data template not being applied?

I'm using Linq To Sql to fill up a listbox with Segment objects, where Segment is designer created/ORM generated class.
<Window x:Class="ICTemplates.Window1"
...
xmlns:local="clr-namespace:ICTemplates"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<DataTemplate x:Key="MyTemplate">
<!-- <DataTemplate DataType="x:Type local:Segment"> -->
// some stuff in here
</DataTemplate>
</Window.Resources>
<ListView x:Name="tvwSegments" ItemsSource="{Binding}" ItemTemplate="{StaticResource MyTemplate}" MaxHeight="200"/>
// code-behind
var queryResults = from segment in tblSegments
where segment.id <= iTemplateSid
select segment;
tvwSegments.DataContext = queryResults;
This works.
However if I used a Typed Data Template (by replacing the x:Key with the DataType attribute on the template, the items all show up with ICTemplates.Segment (the ToString() return value)
The concept is that it should pick up the data template automatically if the Type matches. Can someone spot the mistake here?
Ze Mistake is here
<DataTemplate DataType="x:Type local:Segment"> <!-- doesn't work -->
should be
<DataTemplate DataType="{x:Type local:Segment}">
Came home... made a toy-sample and it worked with this change. Gotta try that # work tomorrow. Sheesh.. for want of 2 curlies..
Update: Found out another gotcha
<DataTemplate x:Key="SegTemplate" DataType="{x:Type local:Segment}"> <!-- doesn't work -->
won't work. Seems like you can have it either with a Key OR DataType attribute. To make this typed data template work.. had to remove the Key attribute and now it works as expected. Behavior is consistent for a HierarchicalDataTemplate too.
<DataTemplate DataType="{x:Type local:Segment}">
This is just a guess, but could it be because the context is set to an IQueryable? If you set the DataContext to a single instance of a Segment, do you get the same result?

Resources