WPF Combobox databinding to a L2S table - wpf

Here is what i have:
a SQL CE database, that holds this Category table, with id and name columns only.
dbml generated with sqlmetal
singleton (static class) that exposes the linq DataContext.
in the code-behind file, i have a property like follows:
private System.Data.Linq.Table<Categories> Categories
{
get
{
return LibraryDataStore.Instance.Categories;
}
}
I want to simply bind the categories to a ComboBox. Can't believe i've been at it for hours now, with no result :(
I don't want to set ItemsSource in the code behind, I want to do this XAML-only, but how?
Most examples i found were defining the data right there in XAML, or setting ItemsSource programatically, but that is not what i want.
Why isn't this, for example, working?
<ComboBox Name="cmbCategory"
Margin="3"
MinWidth="200"
ItemsSource="{Binding Path=Categories}"
DisplayMemberPath="Name"/>
As a side note, i want to say that I find the databinding model of wpf extremely difficult to learn, as it is so thick and there are just SO MANY WAYS to do things.
Later edit:
I found that it works if i set the ItemsSource like this:
var cats = from c in LibraryDataStore.Instance.Categories
select c;
cmbCategory.ItemsSource = cats;
Still, I can't figure it out why it doesn't work in XAML.

You must set the datacontext of the UserControl to LibraryDataStore.Instance. This datacontext will then filter down the visual tree to your combobox (so there is no need to set the datacontext of the combobox itself). Your xaml will then be able to bind to the public property of this object "Categories".
Bea Stollnitz gives a good overview of how to detect problems with databinding (i.e. it failing silently) on her blog -> http://bea.stollnitz.com/blog/?p=52

you need to set the DataContext of your UserControl (or Page) to the current instance :
this.DataContext = this;

Related

How can I bind Text property of TextBox (VIEW) to a vaiable (in VIEWMODEL)

I am a newbie in WPF. I was exploring MVVM Pattern for WPF applications. I am having trouble in binding Text property of a TextBox from VIEW to a variable in VIEWMODEL
Here is the TextBox from MainWindow.xaml
<TextBox x:Name="UsernameTxt" Grid.Row="4" materialDesign:HintAssist.Hint="Username"/>
I just need to know how to bind its Text Property to ViewModel Class in Class Library
Thanks
I think it's possible to give a very generic answer to this very generic question.
If the question changes context this answer is very likely to be deleted but here goes anyhow.
You want your viewmodel to be in the datacontext of the textbox. Because datacontext is inherited down the visual tree this usually means you want to set datacontext of your window to an instance of the viewmodel. Or maybe the usercontrol your textbox is in, but we know nothing about your app so let's just cover the simple scenario.
Your options are to instantiate a viewmodel using code or xaml.
If you look at this article:
https://social.technet.microsoft.com/wiki/contents/articles/31915.wpf-mvvm-step-by-step-1.aspx
That instantiates in xaml.
Note the xmlns is
xmlns:local="clr-namespace:wpf_MVVM_Step01"
That's saying where you see some bit of markup which is prefaced "local:" then go get the class out of this namespace.
To point to a different dll ( a class library ) you need to tell it which assembly. You do that by adding ;assembly=Whicheverdll to your equivalent of that xmlns. And of course that won't be local then so give it a different name. You also need a reference to that dll or project added to the entry point exe.
Once you've done all that and your viewmodel is instantiated into memory and in the datacontext of that textbox you need some sort of binding.
Which the article covers but that will be something like:
<TextBox Text="{Binding YourPublicStringProperty}"/>

Call controls inside view(xaml file) in viewmodel

I want to call controls inside view like button and item template inside viewmodel. Please tell how can I do that. My view contains following
<ItemsControl Name="cDetails"
Width="395"
ItemTemplate="{DynamicResource Test}"
ItemsSource="{Binding ViewModels}"
Visibility="{Binding IsLoaded,
Converter={StaticResource visibilityConverter}}">
<Button Name="btnComplete"
Grid.Column="1"
HorizontalAlignment="Center"
Command="{Binding AuditCommand}"
CommandParameter="1">
Complete
</Button>
Please tell how can I call these items in my viewmodel using vb.net.
Thanks
Accessing your view components from inside your viewmodel is not the way to do things in MVVM. Because it is specifically not designed to work this way, you will have to go out of your way to make it work. You should probably investigate how to accomplish your goals using MVVM properly, or forego using MVVM at all and do the work in your code-behind.
Since you have not described what your goal is, it is hard to provide specific recommendations. In general when using MVVM, you manipulate things in your viewmodel and set properties. Your view binds to these properties so that it updates appropriately as they are being set. Your viewmodel does not directly manipulate the views themselves, only the viewmodel properties that they are bound to.
For example, let's say you are updating the text on a TextBlock. You could do something like this in xaml:
<TextBlock Text="{Binding SomeText}" />
Then, your viewmodel (which should implement the INotifyPropertyChanged interface) defines this property and sets it as desired.
public string SomeText
{
get { return _someText; }
set
{
if (_someText != value)
{
_someText = value;
NotifyPropertyChanged("SomeText");
}
}
}
private string _someText;
...
// At any time, you can set the property, and the
// binding will update the text in the control for you.
SomeText = "Some text";
If you absolutely need to manipulate your views from code (or if you are not using MVVM), the appropriate place for that sort of code is the "xaml.cs" file next to your view (the code-behind). You can assign a name to anything in your xaml using syntax like <TextBlock x:Name="SomeTextBlock" /> and then access it from the code-behind as a member variable with the same name. For example, you could do SomeTextBlock.Text = "Some text". However, this is not usually necessary for the vast majority of use cases if you are using MVVM.
You shouldn't try to access controls directly from the ViewModel. The ViewModel must not know about the View implementation.
Instead, in WPF we connect View and ViewModel through Bindings. Bindings connect Properties of controls in the View, with Properties in the ViewModel.
Commands are a special type of Property that can be bound as actions for controls like Button.
In your example, you would need to have these properties in your ViewModel:
A collection named ViewModels
A boolean named IsLoaded
And an ICommand named AuditCommand
By managing those properties, you should be able to control what's shown in your View and its behavior.
If you need more control, create more Bindings to other properties, or create some events in your ViewModel and manage them from your View's code-behind.

Accessing variables from XAML and object from ViewModel using Code Behind

I'm a newbie in windows phone development. I would like to ask if it is possible to do this scenario. I need to access a variable in XAML using my code behind, then I will add it as an item to my existing list found in my View Model. Therefore, I need to access both of my View Model to get the list and the XAML to get the variable from the resources.
Is this doable? If yes, how can I access it. This is what I have in my current XAML.
<phone:PhoneApplicationPage.Resources>
<system:String x:Key="scanName">SCAN</system:String>
</phone:PhoneApplicationPage.Resources>
Thanks much,
What you're trying to do is a pretty big violation of everything MVVM is about, but it is possible...
With the following lines in the codebehind of your view, you can...
...access the resource string:
var scanName = this.Resources["scanName"];
...access the ViewModel:
var vm = DataContext as MyViewModel;
if (vm == null) return;
vm.ScanHistory.Add(scanName);
That being said, you really shouldn't do this. The idea of MVVM is to decouple ViewModel and View completely and let the WPF binding mechanisms wire it together for you. In your case, as far as I can tell, you should store the scan name somewhere else, either as a resource or a config value, fetch it in your ViewModel and provide a property on your ViewModel to which your View can bind.
I haven't near winphone app so i make simple example on wpf(it's similiar with winphone).
//write string value from dynamic resource into textblock
<TextBlock FontSize="14" Text="{DynamicResource scanName}"/>
//changing resource in codebehind (this is Window in my example)
this.Resources["scanName"] = "new value";
As my mind you scenario is veru specific.Try to read about bindings. May be bindings will be more useful in your scenario.

Wpf SelectedItem wont work for a Combobox in a ListView

I´ve got a problem with a Combobox in a ListView.
I´ve got a class called "Substrate". This class contains an object of a class called "SubstrateType". I want to show the objects of the class "Substrate" in a Listview. Each property of the "Substrate" is presented in the columns of the Listview. For the different "SubstrateType" I want to use a combobox.
In the XAML I tried it like this:
<ComboBox Name="CBType"
ItemsSource="{Binding ElementName=SettingsSubstrate, Path=TypeList}"
SelectedItem="{Binding Path=Substrate.SubstrateType}"
DisplayMemberPath="Description"/>
In the code-behind I got two ObservableCollections. One for all Substrates and one for all possible SubstrateTypes. The combobox displays all SubstrateTypes if you click on it. But the combobox has no selecteditem if you dont select one.
http://i44.tinypic.com/2eakxav.png
Thanks in advance.
I do not know your exact code, but if your ListView rows display objects of type Substrate, then your Binding Path for the SelectedItem should be just SubstrateType because the DataContext of a ListViewItem is already set to the Substrate object:
SelectedItem="{Binding Path=SubstrateType}"
Furthermore, you need to make sure that your SubstrateType instances are actually considered as equal. If the SubstrateType instance in your Substrate object is not exactly the same as the one from the TypeList property, it will not be selected. You can fix that by overriding the Equals(...) method and define your custom comparison for equality.
If this does not work, please provide more code, e.g. the surrounding XAML and the code of Substrate and the code-behind/ViewModel/whatever.

WPF Databinding

Can anyone point me to a good resource (or throw me a clue) to show me how to do DataBinding to controls (ComboBox, ListBox, etc.) in WPF? I'm at a bit of a loss when all my WinForms niceities are taken away from me, and I'm not all that bright to start with...
The best resource I've found for WPF data binding is Bea Costa's blog. Start from the first post and read forward. It's awesome.
I find the tutorial videos at Windows Client .Net equally awesome. Dot Net Rocks TV has also covered it some time ago.
in code behind -- set the DataContext of your list box equal to the collection you're binding to.
private void OnInit(object sender, EventArgs e)
{
//myDataSet is some IEnumerable
// myListBox is a ListBox control.
// Set the DataContext of the ListBox to myDataSet
myListBox.DataContext = myDataSet;
}
In XAML, Listbox can declare which properties it binds to using the "Binding" syntax.
<ListBox Name="myListBox" Height="200"
ItemsSource="{Binding Path=BookTable}"
ItemTemplate ="{StaticResource BookItemTemplate}"/>
And some more links, just in case the above didn't suffice:
Windows Presentation Foundation - Data Binding How-to Topics
- Approx 30 'How To' articles from MSDN.
"The topics in this section describe how to use data binding to bind elements to data from a variety of data sources in the form of common language runtime (CLR) objects and XML. "
Moving Toward WPF Data Binding One Step at a Time
- By WPF guru Josh Smith
"This article explains the absolute basics of WPF data binding. It shows four different ways how to perform the same simple task. Each iteration moves closer to the most compact, XAML-only implementation possible. This article is for people with no experience in WPF data binding."
Here's another good resource from MSDN: Data Binding Overview.
There are three things you need to do:
Bind the ItemsSource of the ComboBox to the list of options.
Bind the SelectedItem to the property that holds the selection.
Set the ComboBox.ItemTemplate to a DataTemplate for a ComboBoxItem.
So, for example, if your data context object is a person having email addresses, and you want to choose their primary, you might have classes with these signatures:
public class EmailAddress
{
public string AddressAsString { get; set; }
}
public class Person
{
public IEnumerable<EmailAddress> EmailAddresses { get; }
public EmailAddress MainEmailAddress { get; set; }
}
Then you could create the combo box like this:
<ComboBox ItemsSource="{Binding EmailAddresses}" SelectedItem="{Binding MainEmailAddress}">
<ComboBox.ItemTemplate>
<DataTemplate>
<ComboBoxItem Content="{Binding AddressAsString}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Now you need to implement INotifyPropertyChanged in both Person and EmailAddress. For the EmailAddresses collection, you could back it with an ObjservableCollection.
Or as an alternative you can use Update Controls .NET. This is an open source project that replaces data binding and does not require INotifyPropertyChanged. You can use whatever collection makes sense to back the EmailAddresses property. The XAML works the same as above, except that you import the UpdateControls.XAML namespace and replace {Binding ...} with {u:Update ...}.

Resources