Bind XAML elements to entities TwoWay - wpf

I want to bind an entity property (say Salary) to a property of a XAML element (like a TextBox.Text)
and use this binding to save Text of TextBox to salary field which is bound as a entity property to 'Text' of some TextBox.
Something like the following :
<Grid DataContext="Employee">
<TextBox Text="{Binding Path=Salary, Mode=TwoWay}"/>
</Grid>

you just can bind Properties in xaml - so your salary have to be a property and not a field. if your Employee is the class with the salary you can set datacontext to an instance of it. you can do it in xaml or codebehind or with binding.
public class Employee //implement INotifyPropertyChanged to get the power of binding :)
{
public decimal Salary {get;set}
}
view.xaml
<Grid>
<Grid.DataContext>
<local:Employee/>
</Grid.DataContext>
<TextBox Text="{Binding Path=Salary, Mode=TwoWay}"/>
</Grid>
you can set the datacontext in many ways

XAML Two-Way Binding, 'Windows Universal' style, step-by-step
In Visual Studio 2017, create a Visual C# blank app (Universal Windows). Name it 'MyProject'.
Add a class Employee to it, and then modify boilerplate code as follows:
// Employee.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace MyProject
{
public class Employee : INotifyPropertyChanged
{
private string salary;
public string Salary
{
get
{
return this.salary;
}
set
{
if (value != this.salary)
{
this.salary = value;
NotifyPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
// This method MUST BE called by the Set accessor of each property for TwoWay binding to work.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
// Constructor with one parameter
public Employee(string annualSalary) { salary = annualSalary; }
}
}
Notice that class Employee implements the INotifyPropertyChanged Interface.
Add class EmployeeViewModel to project, and modify boilerplate code as follows:
// EmployeeViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyProject
{
public class EmployeeViewModel
{
private Employee defaultEmployee = new Employee("50000");
public Employee DefaultEmployee { get { return this.defaultEmployee; } }
}
}
Modify MainPage.xaml.cs boilerplate code as follows
//MainPage.xaml.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace MyProject
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.ViewModel = new EmployeeViewModel();
}
public EmployeeViewModel ViewModel { get; set; }
}
}
Modify MainPage.xaml boilerplate code as follows:
<Page
x:Class="MyProject.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyProject"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!--TextBlock will provide visual feedback that the two-way binding is working-->
<TextBlock x:Name="Control" Text="{x:Bind ViewModel.DefaultEmployee.Salary, Mode=OneWay}" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center"/>
<!--TextBox has two-way binding-->
<TextBox x:Name="Input" Text="{x:Bind ViewModel.DefaultEmployee.Salary, Mode=TwoWay}" Margin="10" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Center"/>
<!--Button does nothing other than allow TextBox to lose focus-->
<Button x:Name="btn1" Content="Hello" Grid.Column="1" Grid.Row="3"
Foreground="Green"
HorizontalAlignment="Center"/>
</Grid>
</Page>
Notice, both 'Input' TextBox and 'Control' TextBlock are bound to the same Salary property of DefaultEmployee. The idea is that you edit and change the salary in the 'Input' TextBox, and then you can visually see the Two-Way binding at work, because the 'Control' TextBlock will update. This happens when the 'Input' TextBox loses focus (it is to allow the change of focus, for instance after pressing TAB key, that the 'Hello' button was added - the button in itself does absolutely nothing).
Build and Run. Modify salary, and either TAB or click button:

No you cant do like that. You cant Set the Class name to the DataContext. It should be the instance of Employee class.

Related

Applying DataTemplates to Sample/Design Data in Expression Blend

I have a ListView that is supposed to display objects of class Sensor, for which I created a simple (for now) DataTemplate.
In order to further design this DataTemplate in Expression Blend, I created Sample Data from Class as shown in the docs (although I am using Blend for Visual Studio 2013, but it seems to be the same).
I can successfully get the Sample Data I created being displayed in a ListView, but it is not using the DataTemplate I created, since the elements displayed seem to belong to a different, "design" namespace:
The qualified name of my class is Miotec.BioSinais.ModeloDomínio.Sensor;
(But) the qualified name of the displayed class is _.di0.Miotec.BioSinais.ModeloDomínio.Sensor.
What am I doing wrong? (code and screenshot below)
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dominio="clr-namespace:Miotec.BioSinais.ModeloDomínio;assembly=Miotec.BioSinais"
mc:Ignorable="d"
x:Class="Miotec.ProtótipoColeta.ColetaConfigView"
x:Name="Window"
Title="ColetaConfigView"
Width="640" Height="480">
<Window.Resources>
<DataTemplate DataType="{x:Type dominio:Sensor}">
<Border>
<TextBlock Text="{Binding Nome}"/>
</Border>
</DataTemplate>
</Window.Resources>
<DockPanel x:Name="LayoutRoot">
<Grid x:Name="PainelCentral">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<DockPanel x:Name="PainelSetupsSensores" Background="#FFB8E6E8"/>
<DockPanel x:Name="PainelSensoresDisponiveis" Background="#FFC5E2A8"
Grid.RowSpan="2" Grid.Column="1"
DataContext="{Binding ReceiverAtivo}"
d:DataContext="{d:DesignData /SampleData/ReceiverSimuladoSampleData.xaml}">
<ListView ItemsSource="{Binding Sensores}" Margin="10"/>
</DockPanel>
</Grid>
</DockPanel>
</Window>
====
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Miotec.BioSinais.ModeloDomínio
{
public abstract class Sensor : INotifyPropertyChanged
{
public abstract string Nome { get; set; }
public virtual int NívelBateria { get; set; }
public virtual int NívelSinalWireless { get; set; }
public virtual EstadoSensor Estado { get; protected set; }
public ObservableCollection<Canal> Canais { get; protected set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void RaisePropertyChanged (string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
==============

WPF: How to bind object to ComboBox

Trying to learn how to bind objects to various types of controls. In this instance, I want to get sample data in my object to appear in ComboBox. The code runs but what appears instead of values (David, Helen, Joe) is text "TheProtect.UserControls.Client")
XAML: (ucDataBindingObject.xaml)
<UserControl x:Class="TheProject.UserControls.ucDataBindingObject"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Width="Auto"
Height="Auto"
mc:Ignorable="d">
<Grid Width="130"
Height="240"
Margin="0">
<ComboBox Width="310"
HorizontalAlignment="Left"
VerticalAlignment="Top"
ItemsSource="{Binding Path=Clients}" />
</Grid>
</UserControl>
C#: ucDataBindingObject.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Controls;
namespace TheProject.UserControls
{
public partial class ucDataBindingObject : UserControl
{
public List<Client> Clients { get; set; }
public ucDataBindingObject()
{
Clients = new List<Client>();
Clients.Add(new Client(1, "David")); // sample data
Clients.Add(new Client(2, "Helen"));
Clients.Add(new Client(3, "Joe"));
InitializeComponent();
this.DataContext = this;
}
}
C# Client.cs
using System;
using System.Linq;
namespace TheProject.UserControls
{
public class Client
{
public int ID { get; set; }
public string Name { get; set; }
public Client(int id, string name)
{
this.ID = id;
this.Name = name;
}
}
}
There are several ways to tell the framework what to display
1) Use DisplayMemberPath on the ComboBox (this will display the named property):
<ComboBox ItemsSource="{Binding Path=Clients}"
DisplayMemberPath="Name"
/>
2) Set ItemTemplate on the ComboBox. This is like #1, except allows you to define a template to display, rather than just a property:
<ComboBox ItemsSource="{Binding Path=Clients}">
<ComboBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Green" BorderThickness="1" Padding="5">
<TextBlock Text="{Binding Path=Name,StringFormat='Name: {0}'}" />
</Border>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
3) Add a ToString() override to source class. Useful if you always want to display the same string for a given class. (Note that the default ToString() is just the class type name, which is why you see "TheProtect.UserControls.Client".)
public class Client
{
// ...
public override string ToString()
{
return string.Format("{0} ({1})", Name, ID);
}
}
4) Add a DataTemplate to the XAML resources. This is useful for associating a given class type with a more complex or stylized template.
<UserControl xmlns:local="clr-namespace:TheProject.UserControls">
<UserControl.Resources>
<DataTemplate DataType="local:Client">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</UserControl.Resources>
// ...
</UserControl>
In DisplayMemberPath, give the name of the property which you want to show in the comboBox. In SelectedValuePath, give the name of the property which you want to select. When you do a ComboBox.SelectedValue, you will get the value of this property.
Trying to get selected value from combobox returns System.Data.Entity.DynamicProxies.x
private void Button_Click(object sender, RoutedEventArgs e){
string _scanner0 = int.Parse(mycmb.SelectedValue.ToString());
string _scanner1 = mycbr.SelectedItem.ToString();
string _scanner2 = mycbr.SelectedValuePath.ToString();
string _scanner3 = mycbr.text.ToString();
}
all these Returns System.Data.Entity.DynamicProxies.x
What should i do?

WPF Binding Syntax Question

The code below is supposed to show a stack of three list boxes, each containing a list of all the system fonts. The first is unsorted, and the second and third are alphabetized. But the third one is empty. I don't see any binding error messages in the VS Output window when debugging.
The markup is:
<Window x:Class="FontList.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FontList"
Title="MainWindow" Height="600" Width="400">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<ListBox Grid.Row="0" ItemsSource="{Binding Source={x:Static Fonts.SystemFontFamilies}}" />
<ListBox Grid.Row="1" ItemsSource="{Binding Path=SystemFonts}" />
<ListBox Grid.Row="2" ItemsSource="{Binding Source={x:Static local:MainWindow.SystemFonts}}" />
</Grid>
The code behind is:
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Media;
namespace FontList
{
public partial class MainWindow : Window
{
public static List<FontFamily> SystemFonts { get; set; }
public MainWindow() {
InitializeComponent();
DataContext = this;
SystemFonts = Fonts.SystemFontFamilies.OrderBy(f => f.ToString()).ToList();
}
}
}
What's wrong with the third binding?
You need to initialize SystemFonts before you call InitalizeComponent. The WPF binding has no way of knowing the property's value changed.
public MainWindow() {
SystemFonts = Fonts.SystemFontFamilies.OrderBy(f => f.ToString()).ToList();
InitializeComponent();
DataContext = this;
}
or better yet, use:
static MainWindow() {
SystemFonts = Fonts.SystemFontFamilies.OrderBy(f => f.ToString()).ToList();
}
public MainWindow() {
InitializeComponent();
DataContext = this;
}
The Bindings are created during InitializeComponent, while SystemFonts is null. After you set it, the binding has no way of knowing that the property's value has changed.
You can also set SystemFonts in a static constructor, which is probably preferable since it's a static property. Otherwise every instantiation of MainWindow will change the static property.
public partial class MainWindow : Window {
public static List<FontFamily> SystemFonts{get; set;}
static MainWindow {
SystemFonts = Fonts.SystemFontFamilies.OrderBy(f => f.ToString()).ToList();
}
...
}

WPF DataContext ... looking for the simplest syntax

In the following XAML UserControl I am binding a few items to properties in the UserControl's linked class.
<UserControl x:Class="Kiosk.EventSelectButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Kiosk"
Height="130" Width="130">
<Grid>
<Button
Style="{DynamicResource DarkButton130x130}"
HorizontalAlignment="Left"
VerticalAlignment="Center">
<Grid Margin="0,0,0,0" Height="118" Width="118">
<Image VerticalAlignment="Top" HorizontalAlignment="Center" Source="image/select_button_arrows.png" />
<Image x:Name="EventImageComponent" VerticalAlignment="Center" HorizontalAlignment="Center" Effect="{DynamicResource KioskStandardDropShadow}" Source="{Binding Path=EventImage}" />
<TextBlock x:Name="SelectTextBlock" Text="{Binding Path=SelectText}" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,-2,0,0" FontSize="10pt" Foreground="#5aaff5" />
<TextBlock x:Name="LabelTextBlock" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,0,0" FontSize="14pt" FontWeight="Bold" Text="{Binding Path=Label}"/>
</Grid>
</Button>
</Grid>
</UserControl>
In the linked class' contstructor I'm applying the DataContext of the items to this, as you can see below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Kiosk
{
/// <summary>
/// Interaction logic for EventSelectButton.xaml
/// </summary>
public partial class EventSelectButton : UserControl
{
public String ValueContainer;
private String _EventImage;
public String EventImage
{
get
{
return _EventImage;
}
set
{
_EventImage = value;
}
}
private String _Label;
public String Label
{
get
{
return _Label;
}
set
{
_Label = value;
}
}
private String _SelectText;
public String SelectText
{
get
{
return _SelectText;
}
set
{
_SelectText = value;
}
}
public EventSelectButton()
{
InitializeComponent();
LabelTextBlock.DataContext = this;
SelectTextBlock.DataContext = this;
EventImageComponent.DataContext = this;
}
}
}
Edit
Although this works as intended, I'm interested to know if there is a simpler way of doing this. (edit, lessons learned.) This won't actually work beyond the initialisation, the public properties will be set, however because the class doesn't use DependentProperties or alternatively, implement INotifyPropertyChanged, binding will not work as expected. (end edit)
For example,
Can I set the DataContext of these items in the XAML to this (as the EventSelectButton instance), and if so, how?
Alternatively, is it possible to inherit the DataContext from the UserControl parent, thus making the Binding Paths simpler.
The only alternatives I've found so far are more verbose, e.g. using the RelativeSource binding method to locate the EventSelectButton Ancestor.
So please, let me know any ways I can improve this binding expression, and any comments on best practices for binding within a UserComponent are much appreciated.
One way is to do the following:
Name your UserControl in your XAML.
Bind the DataContext of the root element (i.e. Grid) to the UserControl.
Like this:
<UserControl x:Name="uc">
<Grid DataContext="{Binding ElementName=uc}">
.
.
.
</Grid>
</UserControl>
Now, you'll ask, why not just set the DataContext of the UserControl itself? Well, this just ensures that setting the DataContext of an instance of the UserControl will still work without affecting the bindings in the UserControl's visual tree. So something like the one below will still work fine.
<Window>
<uc:EventSelectButton DataContext="{Binding SomeDataContext}" Width="{Binding SomeDataContextWidth}"/>
</Window>
EDIT
To make the solution complete requires the properties in the UserControl to be changed to use DependencyProperty objects instead. Below are the updates to the codes:
XAML:
<UserControl x:Class="Kiosk.EventSelectButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Kiosk"
x:Name="root"
Height="130" Width="130">
<Grid x:Name="LayoutRoot" DataContext="{Binding ElementName=root}">
<Button
Style="{DynamicResource DarkButton130x130}"
HorizontalAlignment="Left"
VerticalAlignment="Center">
<Grid Margin="0,0,0,0" Height="118" Width="118" >
<Image VerticalAlignment="Top" HorizontalAlignment="Center" Source="image/select_button_arrows.png" />
<Image Source="{Binding EventImage}" VerticalAlignment="Center" HorizontalAlignment="Center" Effect="{DynamicResource KioskStandardDropShadow}" />
<TextBlock Text="{Binding SelectText}" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,-2,0,0" FontSize="10pt" Foreground="#5aaff5" />
<TextBlock Text="{Binding Label}" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="0,0,0,0" FontSize="14pt" FontWeight="Bold" />
</Grid>
</Button>
</Grid>
</UserControl>
Code-Behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Kiosk
{
public partial class EventSelectButton : UserControl
{
public static readonly DependencyProperty EventImageProperty =
DependencyProperty.Register(
"EventImage",
typeof(string),
typeof(EventSelectButton));
public String EventImage
{
get { return (string)GetValue(EventImageProperty); }
set { SetValue(EventImageProperty, value); }
}
public static readonly DependencyProperty SelectTextProperty =
DependencyProperty.Register(
"SelectText",
typeof(string),
typeof(EventSelectButton));
public String SelectText
{
get { return (string)GetValue(SelectTextProperty); }
set { SetValue(SelectTextProperty, value); }
}
public static readonly DependencyProperty LabelProperty =
DependencyProperty.Register(
"Label",
typeof(string),
typeof(EventSelectButton));
public String Label
{
get { return (string)GetValue(LabelProperty); }
set { SetValue(LabelProperty, value); }
}
public EventSelectButton()
{
InitializeComponent();
}
}
}

Need simple example of WPF binding Objects to Listbox with LINQ

The following example successfully binds objects with a ListBox to display them.
However, I would like to create all the objects in one class and then from another class query them with LINQ to fill my XAML ListBox, what would I need to add this example:
XAML:
<Window x:Class="WpfApplication15.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300"
xmlns:local="clr-namespace:WpfApplication15">
<Window.Resources>
<ObjectDataProvider x:Key="customers" ObjectType="{x:Type local:Customers}"/>
<DataTemplate x:Key="LastNameFirst" DataType="WpfApplication15.Customer">
<StackPanel Margin="10 10 10 0" Orientation="Horizontal">
<TextBlock Text="{Binding Path=LastName}" FontWeight="bold"/>
<TextBlock Text=", "/>
<TextBlock Text="{Binding Path=FirstName}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Source={StaticResource customers}}"
ItemTemplate="{StaticResource LastNameFirst}"/>
</Grid>
</Window>
Code behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication15
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
}
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Customer(string firstName, string lastName)
{
this.FirstName = firstName;
this.LastName = lastName;
}
}
public class Customers : List<Customer>
{
public Customers()
{
this.Add(new Customer("Jim", "Thompson"));
this.Add(new Customer("Julie", "Watson"));
this.Add(new Customer("John", "Walton"));
}
}
}
edit: added ToList call to the LINQ query
You can just assign the ItemsSource of the ListBox using LINQ in code-behind for this. Assuming you give your ListBox a name:
<Window x:Class="WpfApplication15.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:WpfApplication15"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="300" Height="300" Title="Window1">
<Window.Resources>
<DataTemplate x:Key="LastNameFirst" DataType="WpfApplication15.Customer">
<StackPanel Margin="10 10 10 0" Orientation="Horizontal">
<TextBlock FontWeight="bold" Text="{Binding Path=LastName}"/>
<TextBlock Text=", "/>
<TextBlock Text="{Binding Path=FirstName}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox x:Name="lstCustomers"
ItemTemplate="{StaticResource LastNameFirst}"/>
</Grid>
</Window>
You can assign to ItemsSource in the Loaded event:
public partial class Window1 : Window
{
public Window1()
{
this.Loaded += new RoutedEventHandler(Window1_Loaded);
InitializeComponent();
}
void Window1_Loaded(object sender, RoutedEventArgs e)
{
Customers customers = new Customers();
lstCustomers.ItemsSource = customers.Where(customer => customer.LastName.StartsWith("W")).ToList();
}
}
Assuming your LINQ query will change depending on some logic, you can re-assign ItemsSource at the appropriate points.
If you want to bind without dipping into code-behind whenever your query logic changes, you're probably better off using a CollectionViewSource, since it has sorting and filtering capabilities (assuming that's what you're after from using LINQ).
Take a look # http://www.codeplex.com/bindablelinq and you should find a bunch of good examples for this.

Resources