I have little problem with databinding in my current project.
I have an ObservableCollection I want to bind to an ListBox.
public ObservableCollection<GeoDataContainer> geoList = new ObservableCollection<GeoDataContainer>();
...later...
geoListBox.ItemsSource = geoList;
This code works fine. The Listbox has a datatemplate and everything looks perfect.
But I don't want to use C# code for binding. I want to make the binding in the XAML Code.
I am searching for days but I don't get it. These are two lines C# code but to archive this in XAML it seems impossible without creating my own class for my collection or adding a DataProvider or resources or whatever.
Is there no easy way to do it?
All you have to do is expose the collection and bind to it. For example, if you expose it as:
public ICollection<GeoDataContainer> GeoList
{
get { return geoList; }
}
You will be able to bind to it as:
<ListBox ItemsSource="{Binding GeoList}"/>
The "trick" is to make sure that the DataContext of the ListBox is the class that exposes the GeoList property.
Another good way would be instantiating geoList as a resource
<WindowResources>
<l:GeoCollection x:Key="geoList"/>
</WindowResources>
Then you have
GeoCollection geoList = FindResource("geoList") as GeoCollection;
Of course, this is for cases when the data is related to the view only. If this is related to model or modelview, you use DataContext and bind to its properties.
Kent suggestion is the way to go...
On a further note, if you do not wish to set your DataContext to the list, you can also retrieve the property with an another form of binding:
Make sure your root control has a name, i.e. "Root"
{Binding ElementName=Root, Path=GeoList}
Related
In Windows Forms I used:
dataGridView.DataSource = new BindingList<MyItem>();
The equivalent in WPF seems to be:
dataGrid.ItemsSource = new BindingList<MyItem>();
What I don't understand (and perhaps I'm doing something wrong) is that in the WPF case, the binding doesn't seem to be bidirectional. That is to say: when I modify a MyItem, it is not automatically reflected in the view.
Use ObservableCollection<MyItem>.
MyItem must implement INotifyPropertyChanged and raise PropertyChanged when any of its property values changes.
That'll update the grid cells.
If you plan to do anything much with WPF, learn MVVM and use Binding. Assigning a collection to a property doesn't bind it.
XAML:
<DataGrid
x:Name="dataGrid"
ItemsSource="{Binding MyItemCollection}"
...
/>
You can also create a Binding programmatically, if you really want to make a lot of extra work for yourself.
Seems like ObservableCollection has some improvements over BindingList.
I want to bind to the Items.IndexOf(tbXy).
In c# it's easy to access the IndexOf:
tbControl.Items.IndexOf(tbXy)
but in XAML? I tried this:
Value="{Binding Path=Items.IndexOf(tbxY)}"
I also found this suggestions with the help of converters:
http://social.msdn.microsoft.com/Forums/vstudio/en-US/139bed8b-8eb0-4aec-a9c0-521bd7bede91/determining-index-of-a-tabitem?forum=wpf
Any suggestions to do this simple directly binding?
Wouldn't it make more sense to push that logic to the ViewModel? If tbxY is an item that is known in code-behind, couldn't you just create a property on the ViewModel called "SelectedItem" and then bind elsewhere?
You can do some pretty spiffy things with DataTemplates that would really let you do whatever you want with the actual item, once you're bound to it.
I know you can create custom controls and dependency property for wpf controls like expained here http://msdn.microsoft.com/en-us/library/ms753358.aspx, I want to know if you can create custom dependency property in the same way for devExpress Controls ? and how ?
There is no way to bind multiple items in comboxBoxEdit control. I want to create a dependency property called SelectedItems on ComboBoxEdit.
I already created a custom property on normal ComboBox called SelectedEnumeration which binds directy to the enums and gets the value. No need to use ObjectDataProvider.
There is no way to bind multiple items in comboxBoxEdit control.
Wrong. Check DevExpress.Xpf.Editors.CheckedComboBoxStyleSettings
Basically, you can bind ComboBoxEdit.EditValue to a collection, which gets populated with the selected items.
<dxe:ComboBoxEdit ItemsSource="{Binding MyItems}"
EditValue="{Binding SelectedItems}">
<dxe:ComboBoxEdit.StyleSettings>
<dxe:CheckedComboBoxStyleSettings />
</dxe:ComboBoxEdit.StyleSettings>
</dxe:ComboBoxEdit>
ViewModel:
public class SomeViewModel
{
public ObservableCollection<MyClass> MyItems {get;set;}
public ObservableCollection<MyClass> SelectedItems {get;set;}
}
I already created a custom property on normal ComboBox called
SelectedEnumeration which binds directy to the enums and gets the
value. No need to use ObjectDataProvider.
You're putting too much responsibility on the UI, where it does not belong. Create a proper ViewModel and have your data processed by the ViewModel in such a way that it facilitates regular DataBinding to the UI. Don't resort to reflection and other types of uneeded hacks in order to put logic in the wrong layer.
I may be making this more complicated than necessary ... but here goes.
I have my MainPage.xaml, in there I have references to two other UserControl's, ResultsView, and DetailsView.
Inside of the ResultsView, I have a ListBox bound to an ObservableCollection of custom items, I have a DataTemplate that is rendering each item. The item has a CaseID, and when I click on it, it's displayed as a HyperlinkButton, I need a Command I've set in the MainPageViewModel to fire, which handles changing the visibility to hide the ResultsView, and show the DetailsView.
How do I bind the Command of the Hyperlinkbutton to the Command located in my MainPageViewModel?
Thanks in advance!
edit for clarification:
MainPage.xaml
<resultsView:ResultsView/>
<detailsView:DetailsView/>
Each of the two views (ResultsView & DetailsView) have their own ViewModel. So I'm going from my DataTemplate which resides in a ListBox inside my ResultsView, I need to go up to the MainPageViewModel, an extra step than your answer mentioned. Tried your method naming my MainPage.xaml to Name="mainPage", and using that as the ElementName in my HyperlinkButton, but no luck. I'll do some research on the RelativeSource option and see if I can make that work.
Thanks for your help so far.
edit 2: Forgot to add that the DataTemplate is in a ResourceDictionary, not in the ResultsView.
Well, it depends on the specific details, not all of which you've told us, but I can give you some examples.
Let's say that your DataTemplate for the custom items resides in the XAML of the ResultsView user control. That's a good spot for it but you might have put it in a resource dictionary.
As you say, the ListBox is bound to the collection of custom items. Let's further assume that the custom items collection is itself a property in your MainPageViewModel. And you've said clearly that the command you want to bind to is also in MainPageViewModel.
So the problem, which is a very common one, is that you are working inside a template associated with a binding to a collection, and so your DataContext is a custom item. It is no longer the main view-model itself. That's great as you show appropriate properties of the custom item like CaseID. But it's not great when you want to escape to the top-level of view-model.
If what I've said is true, then the ResultsView user control is in fact probably bound to the MainPageViewModel because you haven't "drilled into" the custom items collection yet. So, what you need to do is find a way using the binding syntax to reference the ResultsView user control from inside the DataTemplate for the ListBox. If you can do that, then you've escaped the collection.
There are two main approaches to do this:
ElementName syntax
RelativeSource syntax
I'll describe ElementName syntax and you can look up the other one.
Part 1) Name your ResultsView UserControl element like this:
<UserControl ....
Name="resultsView">
<!-- ... -->
Part 2) Inside your DataTemplate where you are defining the appearance of the hyperlink use the ElementName syntax to refer to that element:
<TextBlock>
<Hyperlink Command="{Binding DataContext.ItemDetailsCommand, ElementName=resultsView}"/>
</TextBlock>
So first we use ElementName to get the ResultsView UserControl element, and then we have a path with two pieces: the first piece is the DataContext property of the ResultsView which gives us the MainPageViewModel (yeah!), and then the property of the command we want to invoke.
That's one way to "escape" the binding and issue commands found at a higher level in the view-model.
Duplicate of :
Why are DataContext and ItemsSource not redundant?
In WPF we can assign list of item to ComboBox in 2 ways
//CODE #1
//WPF
<ComboBox name="cmbItems" ItemSource={Binding} />
//C#
cmbItems.DataContext = someList;
another way, directly assign itemsource
//CODE #2
//WPF
<ComboBox name="cmbItems" ItemSource={Binding} />
//C#
cmbItems. ItemSource = someList;
both serves the purpose, but whats the difference in above snippet? and which is good to use?
DataContext is mostly used on forms, controls etc.
An ItemSource is a relative path to do databinding on that DataContext.
For example when you make a form to edit Person details, then the DataContext would be Person and the different controls on the form will each bind on a seperate property on that object, for example Name, Date of Birth, etc.
In the second example you can leave out the ItemsSource={Binding}.. You are setting the ItemsSource directly to a value in your code behind.. You won't need a binding here. In your first example, you set the DataContext, and use a binding to retrieve it again from the DataContext..
But it doesn't really matter.. for both methods work fine...
I use the following thumb of rule: set it in code behind, if I have the collection available.. Set it in some kind of binding mode, if I need to transform the collection, so that I can use a IValueConverter to do the job...