|
Oke thanks,
Im now working at the earlier hint to put it all in one dataset, but I think I am doing something wrong
DataTable orderTable = dsOrder.Tables["Order"];
DataTable customerTable = dsOrder.Tables["Customer"];
dsOrder.Relations.Add("Order2Customer",
customerTable.Columns["customerID"],
orderTable.Columns["customerID"],
false);
this.view = (CollectionView)CollectionViewSource.GetDefaultView(orderTable);
this.DataContext = orderTable; (the added/changed code in C#)
<TextBox
Text="{Binding Path=orderID, Mode=OneWay}"
IsReadOnly="True"
Height="23" Name="textBox1" Width="Auto" Margin="3" />
<ComboBox
ItemsSource="{Binding Order2Customer}"
SelectedValuePath="customerID"
SelectedValue="{Binding Path=customerID}"
Height="23" Name="cbCustomer" Width="Auto" Margin="3" SelectionChanged="cbCustomer_SelectionChanged">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="Images/salome.gif" Height="Auto" Width="Auto" MaxHeight="40" MaxWidth="40"/>
<TextBlock Name="tbLastName" VerticalAlignment="Center" Text="{Binding Path=lastName}" />
<TextBlock Name="tbComma" VerticalAlignment="Center" Text=", " />
<TextBlock Name="tbFirstName" VerticalAlignment="Center" Text="{Binding Path=firstName}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ComboBox> (an example of my combobox and a textbox I use in XAML.)
The TextBox binds correctly, the comboBox does not. The relationship should work like this right? But it can't seem to bind to the customer fields...
|
|
|
|
|
Try this,
dsOrder.Relations.Add("Order2Customer",
orderTable.Columns["customerID"],
customerTable.Columns["customerID"],
false);
I interchanged the column references.
|
|
|
|
|
Yes I figured out that I should interchange them indeed, but still with no success.
The ComboBox remains empty.
|
|
|
|
|
Have you changed the ItemsSource of the ListView to bind to the DataRelation ?
|
|
|
|
|
First I tried to applied it to a combobox outside of the listview, so I havent altered the listview yet.
But I changed the ComboBox ItemsSource.
<ComboBox
ItemsSource="{Binding Order2Customer}"
SelectedValuePath="customerID"
SelectedValue="{Binding Path=customerID}"
This didn't work sadly.
Then I tried applying it to the ListView like you said:
<ListView Name="testView"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Order2Customer}"
Grid.Row="2" Grid.Column="2" Margin="3">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
Now nothing in the ListView can be accessed anymore... :P So it's completely blank
I hope you see what I am doing wrong Thanks for the help so far ofcourse!
|
|
|
|
|
I am referring to the Microsoft example.
"this.view = (CollectionView)CollectionViewSource.GetDefaultView(orderTable)"
What is this for?? I think you do not need this part.
"this.DataContext = orderTable;"
This is setting the Orders table as DataSource for the Window. Am I right?
Maybe simplify the the view and see if data comes ?
Instead of a ComboBox use a TextBox and bind it to Order and Customer table fields and see if it works. Preferable use some other field also from the Customer Table (other than CustomerID).
<ListView Name="testView"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Order2Customer}"
Grid.Row="2" Grid.Column="2" Margin="3">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=OrderTableProp1}" />
<TextBlock Text="{Binding Path=CustomerTableProp2}"/>
<TextBlock Text="{Binding Path=CustomerTableProp3}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListView>
(Replaces the property names.)
|
|
|
|
|
It works when I just put stuff in like orderID, customerID, orderDate.
But one order can be bound to one customer, but I want to display all of the customers in the combobox, this was working previously outside of the listview, now it works nowhere anymore.
But given the customerID, I want to be able to select the correct customer. But I will do some more research because it's hard to describe. I could put one working source file without datagrid, and one with datagrid online, maybe that would be a little bit more clear? Because you will see what's the problem when you run it.
edit:
http://rapidshare.com/files/200322597/WpfLookupProblem.zip.html[^]
Edit:
No database ofcourse.. but still it can help I think?
modified on Friday, February 20, 2009 6:33 AM
|
|
|
|
|
I was thinking,and came to the conclusion that binding to the relationship would not suffice. I need to bind to the collection of customers, if I bind to the relationship, only one customer could be returned.
So I think im back where we started :P Find out how to set the ItemsSource of a generated combobox :P
|
|
|
|
|
I get a better picture of what you are stuck into. You have to take some more time to design this bugger
The working sample just had a single order displayed. If I understand correct, the problem is when you try to display all the orders together in a DataGrid form. Is that correct ?
You can create a CLR object of customer data. Create a resource in the Window resources,
<local:Customers x:Key="CustomerList"/>
where Customers is CLR object; a collection of Customer information.
Then bind it to the ComboBox inside the ListView, "{Binding Source={StaticResource CustomerList}"
Now, the combobox will have a different datasource than the ListView. But then you will have to handle the combobox selection change etc. in code behind.
I was trying to devise something more concrete.
|
|
|
|
|
The working sample just had a single order displayed. If I understand correct, the problem is when you try to display all the orders together in a DataGrid form. Is that correct ?
Not entirely, I could show them all and edit them all at once in the working example.
But it indeed displays only one.
I am able to display the the datagrid btw, I shall show you how it looks in a screenshot:
http://i42.tinypic.com/w03yfn.jpg[^]
I will try your Recource suggestion, I read about it but have not yet tried it.
|
|
|
|
|
Yes that is what I was trying to say.
Is it necessary to have the combobox at 2 places ?? You could have it on the top part and in the Grid just display.
|
|
|
|
|
I started with the top part, but I wanted to remove it at the end, so I only need it in the datagrid.
|
|
|
|
|
I have not worked much with these resources, how can I add the datatable of customers to a resource? I only see options to add files or strings in the default resource editor?
|
|
|
|
|
This might help you out MSDN[^]
|
|
|
|
|
Thanks, I think this is exactly what I need.
This is what I have so far:
xmlns:src="clr-namespace:WpfLookup"
<Window.Resources>
<src:OrderCustomerDataset x:Key="dsCustomer.Customer" />
</Window.Resources>
(added in the XAML file)
It gives no errors.
But what I really want to bind, is the table in the instance of my dataset, dsCustomer.Customer. I have a feeling though that x:Key is only the name for in the XAML referencing?
I added this
ItemsSource="{Binding Source={StaticResource dsCustomer.Customer}}"
as ItemsSource to the Customer. But it now only displays one entry with one photo and thats it, I feel we are getting closer though
I hope these questions don't bother you, you are a great help to me
|
|
|
|
|
Rolorob wrote: x:Key is only the name for in the XAML referencing
Yes, your right
Rolorob wrote: displays one entry
Is the ListView still bound to the DataRelation ? Is yes, put it back to where it was before
I suspect
IsSynchronizedWithCurrentItem="True" . Try removing the top part of the view which you would not be using and just run the bottom DataGrid part of your code.
If things still don't work, now since you are using a Grid sort of view, you can use a DataTemplate for the ListView instead of the CollectionView.
Rolorob wrote: questions don't bother you
Not at all
Rolorob wrote: you are a great help to me
Thanks
|
|
|
|
|
Nice :p
When I alter the top combobox so that it's just like the bottom.
So remove from C# code:
this.cbCustomer.ItemsSource = dsOrder.Customer;
And add
ItemsSource="{Binding Source={StaticResource Customer}, Path=.}"
It doesn't work anymore then.
When I look at this:
<Window.Resources>
<src:OrderCustomerDataset x:Key="Customer" />
</Window.Resources>
It doesn't really say to me that it is the right instance of the DataSet/DataTable to bind to, how should I refrace that so that it binds to dsOrder.Customer? I think that's the part that's missing
|
|
|
|
|
Well, you need to design the stuff as I mentioned earlier. Why dont you have a Wrapper Object containing Orders and Customers. You bind your main Window to this wrapper. Then, bind the Orders Grid View to DataContext.Orders and the customer combobox to DataContext.Customers (where DataContext is the datacontext of the main Window which you can reference it in the nested objects using the word "DataContext").
The path you are taking might also work. I do not know what OrderCustomerDataset is ?? If it is an object having a list of Customers then,
ItemsSource="{Binding Source={StaticResource Customer}, Path=ListOfCustomers}"
Remember, you will also need to handle the display of the appropriate customer in the combobox based on the CustomerId of the Order. On changing the customer the customerid in the orders table also has to be updated. You can use a ValueConverter(or MultiValueConverter) to drive the SelectedValue of ComboBox based on parameters and handle the combobox selection change.
Hope that helps(or makes matters worse??)
|
|
|
|
|
|
I am trying to follow Karl Shifflett or Josh Smith MVVM pattern but I don't fully comprehend how I can make this happen. And I am hoping that I can get some help here.
I have an Object_A with some attributes, and an ObservableCollection<object_a>. Then in the UI I have a "view" of the attributes of Object_A, with a list box below which has the ObservableCollection<object_a>. What I want to be able to do is to be able to edit the attributes of the selected item in the list box and I want to be able to add a new Object_A if the "Add" button is clicked. This is where I get confused, because it is technically not bound any longer to the object in the list box it is it's own object that needs to be inserted into the ObservableCollection<object_a>.
I have two separate views and two view-models, and the "Add" button on the Object_A view-model, raises an event and passes the new Object A to the View-Model for the collection of Object_A, and if I set a break point and look at the Collection View-Model's ObservableCollection<object_a> which the UI is bound to the ObservableCollection<object_a> shows that the count has changed, but the UI doesn't reflect this change, is like the UI doesn't get notified that the ObservableCollection<object_a> has changed and the List box should be updated.
What should I be doing to get the UI to "refresh" itself when a new Object_A is being inserted into the ObservableCollection<objecta>?
|
|
|
|
|
Well - if you add the object to the ObservableCollection, the UI will be updated for you automatically (assuming you've used the appropriate bindings). How have you set up the Mode on your listbox? That's possibly where you are having a problem - try setting it to OneWay.
|
|
|
|
|
I was thinking it could be something with me overriding the OnCollectionChanged, but when I took that completely out, it still didn't work so I was thinking that it was something else.
|
|
|
|
|
If I could see the markup, it will be easier to get an idea.
|
|
|
|
|
Here is the XAML
<listbox x:name="lstScreens" xmlns:x="#unknown"> IsSynchronizedWithCurrentItem="True"
Grid.Row="1"
ItemsSource="{Binding Path=ReportScreens}"
ItemTemplate="{DynamicResource ScreenTabScreen}"
Margin="10,0,10,10">
And I can email any/all of the code for these areas if you would like.
|
|
|
|
|
Sure - my email is pete dot ohanlon at gmail dot com.
|
|
|
|