Binding up using data binding - c#

I've an
ObservableCollection<Products> products
in my Model class and another
ObservableCollection<Foo> foo
in the ViewModel class.
I've binded the products to a Developer Express GridControl and I've a column in that grid that is a ComboBox.
How I can bind the foo collection in the ComboBox?
Here's the way I've binded the products to the GridControl
<dxg:GridControl ItemsSource="{Binding Path=Model.Products}" ...

Something like this should work:
<ComboBox ItemsSource="{Binding Path=DataContext.foo, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type dxg:GridControl}}}"/>

Related

Populating DataGridComboBox in Grid with SelectedItem

I am trying to get a DataGridComboBoxColumn (Or DataGridTemplateColumn with a ComboBox) to populate a list of ports and default each row to the port that is already stored in the database. I have got a DataGridTemplateColumn with a ComboBox populating the Ports, but I cannot seem to get it to select what is already stored in the database.
I'm using Entity Framework and I have 2 tables, 'Route' and 'Port'. 'Route' has 2 foreign keys for a 'Destination Port' and a 'Arrival Port'.
I have 2 ObervableCollections, one for the list of ports, and another for the list of routes. In the routes collection there is a 'Port1' and 'Port2' for Destination/Arrival respectively.
This is what I currently have:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding DataContext.PortCollection, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
DisplayMemberPath="PortName"
SelectedItem="{Binding DataContext.RouteCollection, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
SelectedValue="{Binding DataContext.Port1, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}"
SelectedValuePath="PortId">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
But as I said it is only listing the available ports, and is otherwise blank. Sorry if I haven't made myself too clear, I'm not very good at articulating, generally.
Here are my collections:
public ObservableCollection<Port> PortCollection { get; set; }
//List of Routes
private ObservableCollection<Route> _RouteCollection;
public ObservableCollection<Route> RouteCollection
{
get { return _RouteCollection; }
set
{
_RouteCollection = value;
Set(() => RouteCollection, ref _RouteCollection, value);
}
}
There's clearly something obvious wrong as this must be quite a common thing to do, but I've been going mad for 4 hours on this just getting this far! :(
Many thanks
"Port1" is supposed to be a property of the item in the DataGrid's Items collection. It should have the same type as the PortId property of the Port class.
You can then bind the SelectedValue property directly to it like this:
<ComboBox ItemsSource="{Binding DataContext.PortCollection, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
DisplayMemberPath="PortName"
SelectedValue="{Binding Port1}"
SelectedValuePath="PortId">
The default DataContext of an element in the CellTemplate of a DataGridTemplateColumn is the corresponding item in the Items/ItemsSource collection of the parent DataGrid.
Note that if the type of the Port1 property is Port you should use the SelectedItem property instead of SelectedValue:
<ComboBox ItemsSource="{Binding DataContext.PortCollection, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
DisplayMemberPath="PortName"
SelectedItem="{Binding Port1}">

Bind ComboBox in DataGrid to collection in view

I have a view that is bound to my usercontrol. On my usercontrol I have a datagrid which is bound to a collection from my view. One column in that datagrid is a DataGridComboBoxColumn and I need to bind it to a different collection in my view. The binding of the datagrid looks like this:
DataContext="{Binding .}" ItemsSource="{Binding VictimVillages}"
The datacontext is the view and VictimVillages is the collection I want to display in the datagrid.
I have tried to access the collection I want to display in the combobox with
ItemsSource="{Binding Path=Patterns,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Views:ViewPlanner}}}"
The name of the collection is Patterns, the type of the view is "ViewPlanner", which is in the Views namespace.
I have create a diagram of the dependencies. I need help to figure out the yellow part.
when using RelativeSource Binding you(mostly) have to use DataContext.YourProperty in your Binding Path.
if your datacontext from the DataGrid also have the Patterns Collection you can do this
ItemsSource="{Binding Path=DataContext.Patterns,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type DataGrid}}}"
i often use "MarkerInterface" for Relative bindings. that mean empty interfaces that i can add to my views.
public interface IDataContextMarker4PatternCollection {}
now add this interface to your view/usercontrol where the Pattern Collection Property is in the Datacontext.
and now you can simply use RelativeSourceBinding
ItemsSource="{Binding Path=DataContext.Patterns,RelativeSource={RelativeSource AncestorType={x:Type local:IDataContextMarker4PatternCollection }}}"

How to extract data from datagrid in wpf?

I have difficulty in extracting data from datagrid. Since I was using selectionchange event on datagrid. I managed to get the selected row and column index. But I couldn't find any properties to get the exact data from the datagrid or datagridrow or selectedcells. Hope to get some advice from you guys, cheers.
Bind your DataGrid to an ItemsSource containing your data, and then your SelectedItem will be the item in your ItemsSource.
You had a comment above of using ComboBoxes, so here's an example:
<DataGrid ItemsSource="{Binding MyData}" AutoGernateColumns="False">
<DataGrid.Columns>
<DataGridComboBoxColumn ItemsSource="{Binding Path=DataContext.ComboBoxOptions, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
DisplayMemberPath="Name"
SelectedValuePath="Id"
SelectedValueBinding="OptionId" />
</DataGrid.Columns>
</DataGrid>
The DataContext for your DataGrid would contain
ObservableCollection<SomeItem> MyData { get; set; }
ObservableCollection<Option> ComboBoxOptions{ get; set; }
The SomeItem class would have a property of OptionId, and the Option class would have
an Id and Name field.
In this example, when you select an item in the DataGrid the DataGrid.SelectedItem would contain the SomeItem
Remember, in WPF your Data (DataContext) is your application, and your UI elements like ComboBoxes, TextBoxes, DataGrids, etc are all just a pretty interface to let the user interact with your Data
In your MouseDoubleClick Event , use the dataGrid1.SelectedIteam as Object.
The code should be like somewhat like following :
private void dataGrid1_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
edit(this.dataGrid1.SelectedItem as YourObject);
}

Binding beyond the DataContext

I have a DataTemplate for templating my ItemsControl's items which are TimeSheet's Details.
I have couple of TextBox representing certain values of my TimeSheet's Details but their IsEnabled property depends on the TimeSheet itself, not the details.
<ItemsControl
ItemsSource="{Binding Path=TimeSheet.TimeSheetDetails}"
ItemTemplate="{StaticResource TimeSheetDetail}"
/>
<DataTemplate x:Key="TimeSheetDetail">
<TextBox
Text="{Binding Houre}"
IsEnabled="Binding ??????">
</DataTemplate>
Since the IsEnabled property cant be found in the TimeSheetDetails but can be found in my ViewModel, i would like to bind directly to my ViewModel's Property but when i try binding, to my ViewModel from my DataTemplate, it only seems to look in my TimeSheetDetail.
How can i access my ViewModel's public property directly?
You can bind to your parent's DataContext:
{Binding DataContext.IsEnabled,
RelativeSource={RelativeSource FindAncestor, AncestorType=ItemsControl}}

MVC design issue

I'm having an application using MVC. It has a canvas and property grid. When an item is selected in the canvas. The property grid should display its details.
So I made an event listener and when item is selected in the canvas it raises an event to the controller which pass the selected item to the property grid to display the details.
Model :
Item object containing name, description
Controller :
protected Controller(object model, FrameworkElement view)
{
this._model = model;
this._view = view;
}
public virtual void Initialize()
{
View.DataContext = Model;
}
View :
<TextBlock>Status</TextBlock>
<ComboBox ItemsSource="?????"/>
Where view is the property grid and model is the selected item.
The problem is in the property grid there is a dropdown list containing lookup values how can I get the dropdown values given that the datacontext of the property grid has already been set to the selected item which doesn't contain reference to these lookup items.
I know that it's easy to use custom code to do that. But I don't want to violate the MVC aproach.
Bind to a source rather than DataContext, sources are provided by ElementName, RelativeSource & Source, so you can name the View for example and use ElementName to get it as source then the Path could be DataContext.LookupValues or whatever your property in the model (- the DataContext of the View is your model -) is called.
e.g.
<Window ...
Name="Window">
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" />
<ComboBox ItemsSource="{Binding ElementName=Window, Path=DataContext.Occupations}"
SelectedItem="{Binding Occupation}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- ... --->
Edit: Your problem seems to be that you do not pass the information you need, consider a design which still grants you access to more than just the SelectedItem of some list, e.g.
<Window ...
Name="Window">
<ListBox Name="listBox" ItemsSource="{Binding Data}" />
<ContentControl DataContext="{Binding ElementName=listBox, Path=SelectedItem}">
<ComboBox ItemsSource="{Binding ElementName=Window, Path=DataContext.Occupations}"
SelectedItem="{Binding Occupation}" />
</ContentControl>
<!-- ... --->
The DataContext of the ContentControl may be the SelectedItem of the ListBox but the ComboBox inside can still reference the DataContext of the Window which should provide the necessary information.
This is similar to my first example in that the DataContext inside the DataTemplate is always an item of the collection but you can access external DataContexts using sources in your bindings.

Categories

Resources