How to set an item as selected in a combobox - wpf

It seems nobody has yet found a way to set the comboboxitem as selected with a SelectedItem="Binding Property".
Is the solution to use a IsSelected Property in the ViewModel object within the combobox itemssource?

Our successful approach for binding a combobox is the following...
<ComboBox
ItemsSource="{Binding Path=AllItems}"
SelectedItem="{Binding Path=CurrentItem, Mode=TwoWay}" />
<TextBlock Text="{Binding Path=CurrentItem, Mode=TwoWay}" />
class public ItemListViewModel
{
public ObservableCollection<Item> AllItems {get; set;}
private Item _currentItem;
public Item CurrentItem
{
get { return _currentItem; }
set
{
if (_currentItem == value) return;
_currentItem = value;
RaisePropertyChanged("CurrentItem");
}
}
}

Not sure why you can't data bind to SelectedItem on a ComboBox without seeing your code. Below shows you how to do it using a CollectionView which has current item management built in which comboboxes supports. CollectionView has a CurrentItem get property you can use to get currently selected.
XAML:
<Window x:Class="CBTest.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">
<StackPanel>
<ComboBox
ItemsSource="{Binding Path=Names}"
IsSynchronizedWithCurrentItem="True">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Text="{Binding Path=Names.CurrentItem}" />
</StackPanel>
</Window>
Code behind:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Data;
namespace CBTest
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
DataContext = new VM();
}
}
public class VM
{
public VM()
{
_namesModel.Add("Bob");
_namesModel.Add("Joe");
_namesModel.Add("Sally");
_namesModel.Add("Lucy");
Names = new CollectionView(_namesModel);
// Set currently selected item to Sally.
Names.MoveCurrentTo("Sally");
}
public CollectionView Names { get; private set; }
private List<string> _namesModel = new List<string>();
}
}

what i found is that in combobox soure code, selecteditem is set by using list selectedindex
combobox using
public object SelectedItem {
get {
int index = SelectedIndex;
return (index == -1) ? null : Items[index];
}
set {
int x = -1;
if (itemsCollection != null) {
//bug (82115)
if (value != null)
x = itemsCollection.IndexOf(value);
else
SelectedIndex = -1;
}
if (x != -1) {
SelectedIndex = x;
}
}
}
this method always return -1 or null every time you set Selecteditem by code
x = itemsCollection.IndexOf(value);
its reported as bug (82115) in combobox code
so the working method is to use SelectedIndex directly and bind to it instead of SelectemItem property and if you want you can read only the item from binding to the SelectedItem property or obtain it in your code using ItemsSource itself.
This working for me fine.

Related

How to prevent user from selecting the same value from more than one combobox in wpf

I have a simple class as such:
public class Item
{
public int ID{get;set;}
public string Name{get;set;}
}
I have a List of this class in my Mainwindow.xaml.cs as such:
public List<Item> AllItems=GetAllItems();
I have four properties of Item class in my Mainwindow.xaml.cs as such:
public Item Item1{get;set;}
public Item Item2{get;set;}
public Item Item3{get;set;}
public Item Item4{get;set;}
This List:AllItems is databinded to four Comboboxes as under:
<ComboBox x:Name="cmbCode1" ItemsSource="{Binding AllItems}" DisplayMemberPath="ID" SelectedValuePath="ID" SelectedValue="{Binding Item1.ID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Item1,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<ComboBox x:Name="cmbCode2" ItemsSource="{Binding AllItems}" DisplayMemberPath="ID" SelectedValuePath="ID" SelectedValue="{Binding Item1.ID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Item1,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<ComboBox x:Name="cmbCode3" ItemsSource="{Binding AllItems}" DisplayMemberPath="ID" SelectedValuePath="ID" SelectedValue="{Binding Item1.ID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Item1,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<ComboBox x:Name="cmbCode4" ItemsSource="{Binding AllItems}" DisplayMemberPath="ID" SelectedValuePath="ID" SelectedValue="{Binding Item1.ID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding Item1,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
I have four TextBoxes corresponding to these four Comboboxes as such:
<TextBlock x:Name="txtName1" Text="{Binding Item1.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName2" Text="{Binding Item2.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName3" Text="{Binding Item3.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock x:Name="txtName4" Text="{Binding Item4.Name,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}"/>
What i want is that the user should never be able to select the same ID from more than one combobox.
Is there some simple way that could be done,especially using xaml only?How can i hide or show the items selected/unselected from other comboboxes so that the user can't select the same ID from more than one combobox ever?
So far i have tried to send the selected Item and the entire List to a MultivalueConverter and eliminating/adding items to the Lists there itself,but this seems too meesy.Any other better idea would be appreciated.
You could have a separate list for each of your ComboBoxes. You could then add a LostFocus event handler to each of them. You could use this to repopulate the lists for the other ComboBoxes to exclude the selection.
For example, if I've got 5 items in my list; initially I'll be able to select all 5 in any of my ComboBoxes. When I select Item1 in ComboBox1 the LostFocus event handler will update the lists behind ComboBoxes 2-4 to remove Item1. When I then select Item2 in ComboBox2 the LostFocus event handler will then update the lists behind ComboBoxes 3 and 4 to remove Item2. And so on...
An alternative approach might be to let the user select whatever they like and then run some kind of validation on the selected values to make sure that they're unique. This article goes through some of your options.
Personally, I'd go with the second approach; perhaps with a message above the textboxes indicating that the selection must be unique. You could indicate any errors and block any actions that rely on the selection while it's invalid but you're not having to update your data constantly which will probably lead to a smoother UI.
You can use the code to hide the selected item in different combobox
for (int count = 0; count <= cmb1.Items.Count -1; count++)
{
if((ComboBoxItem)(cmb1.Items[count])).SelectedValue==TextBox1.Text)
((ComboBoxItem)(cmb1.Items[count])).Visibility = System.Windows.Visibility.Collapsed;
}
This code you can write in selected event of the comboxes.
I guess you can write the same logic using triggers in XAML
You should handle this kind of logic in your view models. Here is an example for you that should give you the idea:
View Model:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
AllItems = new List<Item>() { new Item { Name = "1" }, new Item { Name = "2" }, new Item { Name = "3" }, new Item { Name = "4" } };
}
public List<Item> AllItems { get; set; }
private Item _item1;
public Item Item1
{
get { return _item1; }
set
{
_item1 = value;
NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
private Item _item2;
public Item Item2
{
get { return _item2; }
set
{
_item2 = value;
NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
private Item _item3;
public Item Item3
{
get { return _item3; }
set
{
_item3 = value; NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
private Item _item4;
public Item Item4
{
get { return _item4; }
set
{
_item4 = value;
NotifyPropertyChanged();
if (value != null)
value.CanSelect = false;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Item : INotifyPropertyChanged
{
public int ID { get; set; }
public string Name { get; set; }
private bool _canSelect = true;
public bool CanSelect
{
get { return _canSelect; }
set { _canSelect = value; NotifyPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
XAML:
<Style x:Key="icstyle" TargetType="ComboBoxItem">
<Setter Property="IsEnabled" Value="{Binding CanSelect}" />
</Style>
...
<ComboBox x:Name="cmbCode1" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item1}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>
<ComboBox x:Name="cmbCode2" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item2}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>
<ComboBox x:Name="cmbCode3" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item3}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>
<ComboBox x:Name="cmbCode4" ItemsSource="{Binding AllItems}" SelectedItem="{Binding Item4}" DisplayMemberPath="Name" ItemContainerStyle="{StaticResource icstyle}"/>

wpf binding combobox to observable collection

I have an ObservableCollection that gets it's data from a DataTable that is populate from a Postgres Database. I need to bind this ObservableCollection to a ComboBoxColumn in a DataGrid. I have seen quite a lot of examples on how to do this, yet I'm constantly missing something.
Edit: This is the new updated code and it is working except for the INotifyPropertyChanged that I have set only to "name" (yet)
namespace Country_namespace
{
public class CountryList : ObservableCollection<CountryName>
{
public CountryList():base()
{
// Make the DataTables and fill them
foreach(DataRow row in country.Rows)
{
Add(new CountryName((string)row.ItemArray[1], (int)row.ItemArray[0]));
}
}
}
public class CountryName: INotifyPropertyChanged
{
private string name;
private int id_country;
public event PropertyChangedEventHandler PropertyChanged;
public CountryName(string country_name, int id)
{
this.name = country_name;
this.id_country = id;
}
public string Name
{
get { return name; }
set {
name = value;
OnPropertyChanged("CountryName");
}
}
public int idcountry
{
get { return id_country; }
set { id_country = value; }
}
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
}
XAML:
xmlns:c="clr-namespace:Country_namespace"
<Windows.Resources>
<c:CountryList x:Key="CountryListData"/>
</Windows.Resources>
DataGrid Column:
<dg:DataGridTemplateColumn Header="country">
<dg:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource CountryListData}}" DisplayMemberPath="Name"></ComboBox>
</DataTemplate>
</dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>
first of all. you can just bind to public properties.
country_ seems no public property.
second if binding not work you always have to check datacontext first and binding path second. you can use Snoop to do this at runtime
EDIT:
you did not post your itemssource for your grid. so some assumptions here.
<DataGrid ItemsSource="{Binding MySource}">
...
<ComboBox ItemsSource="{Binding MySourcePropertyForCountries}"/>
--> this would work when your MySource object item has a public property MySourcePropertyForCountries.
but if your want to bind your combobox to a list wich is outside the MySource object. then you have to use some kind relativeSourcebinding or elementbinding.
<DataGrid x:Name="grd" ItemsSource="{Binding MySource}">
...
<ComboBox ItemsSource="{Binding ElementName=grd, Path=DataContext.MyCountries}"/>
--> this would work when the datacontext of the datagrid has a property MyCountries

TwoWay Binding of a ComboBox to a static property

-------EDIT------
So, i figured that my code is correct and so are the code snippets from all of your answers. Thanks for that. My problem is that my dev-maschine runs .NET4.5 which behaves differently! The very same program (compiled against .NET4.0) runs correct on a maschine with .NET4.0 but not on a maschine with .NET4.5!
So here is my revised question.
-------EDIT------
First, the simple example how i two-way bind my combobox to my data context:
View model:
public class MainWindowViewModel
{
public List<String> MyElements { get; set; }
public string SelectedElement { get; set; }
public MainWindowViewModel()
{
MyElements = new List<string>() {"a", "b", "c"};
SelectedElement = "a";
}
}
and code-behind
private readonly MainWindowViewModel _viewModel = new MainWindowViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = _viewModel;
}
and my xaml
<ComboBox
ItemsSource="{Binding MyElements, Mode=OneWay}"
SelectedItem="{Binding SelectedElement}" />
This works fine and if i select an item whith the combobox, it is bound to my view model.
OK, now i want to make my viewModel static but still two-way bind the selectedItem. I try this:
public class MainWindowViewModel
{
public static List<String> MyElements { get; set; }
public static string SelectedElement { get; set; }
static MainWindowViewModel()
{
MyElements = new List<string>() {"a", "b", "c"};
SelectedElement = "a";
}
}
I do not need to set the datacontext in the Code-behind anymore and i know, that xaml needs an instance for two-way binding, so i have still the default constructor. I then bind the combobox
<Window.Resources>
<me:MainWindowViewModel x:Key="model"/>
</Window.Resources>
<StackPanel>
<ComboBox
ItemsSource="{Binding Source={x:Static me:MainWindowViewModel.MyElements}, Mode=OneWay}"
SelectedItem="{Binding Source={StaticResource model}, Path=SelectedElement}" />
</StackPanel>
The initial value is properly bound, but if i select another item with the combobox it it not reflected in my viewModel. What am i doing wrong?
EDIT:
If I use the exact same binding string for a TextBox and change the text in the box, it is reflected in the property.
<TextBox Text="{Binding Source={StaticResource model}, Path=SelectedElement}"/>
So obviously my binding string is correct but the way i use the combobox seems to be wrong. I also tried to bind SelectedValue instead... no change either.
Checked just in a sample project, works fine
public class ViewModel
{
static ViewModel()
{
Items=new ObservableCollection<string>();
SelectedItem = "222";
Items.Add("111");
Items.Add("222");
Items.Add("333");
Items.Add("444");
Items.Add("555");
}
private static string _selectedItem;
public static string SelectedItem
{
get { return _selectedItem; }
set { _selectedItem = value;
MessageBox.Show("Item " + value + " was selected");
}
}
private static ObservableCollection<string> _items;
public static ObservableCollection<string> Items
{
get { return _items; }
set { _items = value; }
}
}
and xaml
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my="clr-namespace:WpfApplication1"
Title="MainWindow" Height="200" Width="300">
<Grid>
<Grid.Resources>
<my:ViewModel x:Key="viewM"/>
</Grid.Resources>
<ComboBox Height="23" HorizontalAlignment="Left" Margin="101,12,0,0" Name="comboBox1" VerticalAlignment="Top" Width="146"
ItemsSource="{Binding Source={x:Static my:ViewModel.Items}, Mode=OneWay}"
SelectedItem="{Binding Source={StaticResource viewM}, Path=SelectedItem}" />
</Grid>
</Window>
I have uploaded sample.
You're being confused between instances and static properties: you don't need to bind a static object.
<ComboBox
ItemsSource="{x:Static me:MainWindowViewModel.MyElements}"
SelectedItem="{x:Static me:MainWindowViewModel.SelectedElement}" />
And you should implement INotifyPropertyChanged nevertheless.
Binding is about resolving the right instance from which you want to fetch data.
If there is no meaning of instance, there is no need for binding.

WPF : Get particular field from ObservableCollection

I have an ObservableCollection named SeiveList. I want all the SeiveIdSize from the list (except the last one as it is of no use) and set the DataContext for a Combobox. I added
seiveCmb.DataContext = GlobalUtils.SeiveList;
seiveCmb.DisplayMemberPath = // WHAT SHOULD GO HERE. hOW TO ONLY SHOW SeiveIdSize
// XML
<ComboBox Name="seiveCmb" ItemsSource="{Binding}" Grid.Column="1" Grid.Row="1" Margin="2" SelectedIndex="0" ></ComboBox>
EDITED AS PER Sebastian's suggestion : At present, I just tried out with list for combobox.
My Seive class :
public class Seive : INotifyPropertyChanged
{
// Other Members
private bool isSelected;
public bool IsSelected
{
get { return isSelected; }
set
{
isSelected = value;
OnPropertyChanged("IsSelected");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string p)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(p));
}
}
In my Window .xaml file :
<Window.Resources>
<CollectionViewSource Source="{Binding Path=comboSeives}"
x:Key="comboSeivesFiltered"
Filter="ComboSeiveFilter">
</CollectionViewSource>
</Window.Resources>
<ComboBox Name="seiveCmb" ItemsSource="{Binding Source={StaticResource comboSeivesFiltered}}" DisplayMemberPath="SeiveIdSize"
Grid.Column="1" Grid.Row="1" Margin="2" SelectedIndex="0"
></ComboBox>
In Window .cs file :
public ObservableCollection<Seive> comboSeives { get; set; }
// Initial original data in Window_Loaded method
comboSeives = GlobalUtils.SeiveList;
public void ComboSeiveFilter(object sender, FilterEventArgs e)
{
Seive sv = e.Item as Seive;
// Add items those is != "TOTAL" and isSelected == false
if (sv.SeiveIdSize != "TOTAL" && sv.IsSelected == false)
e.Accepted = true;
else
e.Accepted = false;
}
If the id is "TOTAL" or isSelected is false (i.e. not added to the grid), then only return true and it will add up in it. With initial all records have isSelected = false.
This is what I have understood from youe explaination and help of this site. and have implemetned this. But in the runtime, I don't see any thing in the combobox. I tried to debug adding break at filter method, but it is never reached there. Can you point out where I am making mistake from the above code.
aNY HELP IS Appreciated.
Thanks
I understand that you want your Collection to be filtered, removing one element. One way to do this is create a CollectionView in your Window.Resources and apply a filter Method - as demonstrated and explained here.
<Window.Resources>
<CollectionViewSource Source="{Binding Path=SeiveList}"
x:Name="seiveListFiltered"
Filter="MyFilter">
</CollectionViewSource>
</Window.Resources>
Your code insinuates that in your case the collection is the DataContext of the Window. This must be changed to match your new Resource:
<ComboBox ItemsSource="{Binding Source={StaticResource seiveListFiltered}}"/>
Note that this will fill your ComboBox with items that resemble the output of your SeiveItem.ToString()-Method (Actually, I don't know the class name of the Item). Use the DisplayMemeberPath-Property to set the name of the Property to display instead.
<ComboBox DisplayMemberPath="SeiveIdSize" ItemsSource="{Binding Source={StaticResource seiveListFiltered}}"/>

ComboBox wpf not item not being selected

I am trying to bind a combo box to a list of objects, and it works great, besides the selected value, am I missing somethign?
<ComboBox ItemsSource="{Binding OrderInfoVm.AllCountries}"
SelectedValuePath="country_code" DisplayMemberPath="country_name"
SelectedValue="{Binding OrderInfoVm.BillingCountry}" />
Basically I want to bind value to country codes and set the selected value to the country code bound to OrderInfoVm.BillingCountry (which implements INotifyPropertyChanged)
Initially when the control loads selected value is empty, but on click BillingCountry is populated. Selected value does not seem to change. How can I remedy that?
I do agree with Alex that using SelectedItem gives the desired behaviour. See the code below. It works and will hopefully help you further:
<Window x:Class="SelectedValueSpike.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">
<StackPanel>
<ComboBox ItemsSource="{Binding OrderInfoVm.AllCountries}"
SelectedValuePath="country_code" DisplayMemberPath="country_name"
SelectedItem="{Binding OrderInfoVm.BillingCountry}"
IsSynchronizedWithCurrentItem="True"
Name="AllCountriesBox"/>
<TextBox Text="{Binding ElementName=AllCountriesBox, Path=SelectedValue}"/>
<Button>
Change the textbox to "Ca","NL",or "US" and click!
</Button>
</StackPanel>
</Window>
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
namespace SelectedValueSpike
{
public partial class Window1 : Window
{
public OrderInfoVm OrderInfoVm{ get; set;}
public Window1()
{
InitializeComponent();
OrderInfoVm=new OrderInfoVm();
OrderInfoVm.AllCountries.Add(new Country("US","US of A"));
OrderInfoVm.AllCountries.Add(new Country("NL","Netherlands"));
OrderInfoVm.AllCountries.Add(new Country("Ca","Canada"));
OrderInfoVm.BillingCountry = OrderInfoVm.AllCountries[1];
DataContext = this;
}
}
public class OrderInfoVm:INotifyPropertyChanged
{
public OrderInfoVm()
{
AllCountries=new ObservableCollection<Country>();
}
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<Country> _allCountries;
public ObservableCollection<Country> AllCountries
{
get { return _allCountries; }
set
{
_allCountries = value;
OnPropertyChanged("AllCountries");
}
}
private Country _billingCountry;
public Country BillingCountry
{
get { return _billingCountry; }
set
{
_billingCountry = value;
OnPropertyChanged("BillingCountry");
}
}
private void OnPropertyChanged(string property)
{
if(PropertyChanged!=null)
PropertyChanged(this,new PropertyChangedEventArgs(property));
}
}
public class Country
{
public string country_code { get; set; }
public string country_name { get; set; }
public Country(string code, string name)
{
country_code = code;
country_name = name;
}
}
}
Maybe you are trying to implement something similar to this: Bound ComboBox
Try changing it to SelectedItem and set Mode=TwoWay...
<ComboBox ItemsSource="{Binding OrderInfoVm.AllCountries}"
SelectedValuePath="country_code" DisplayMemberPath="country_name"
SelectedItem="{Binding OrderInfoVm.BillingCountry, Mode=TwoWay}" />
Edit: You may not need to change it to SelectedItem, perhaps just setting TwoWay will work, but that is how I've done it in my own code.
Please ensure that you've specified correct binding path.
Try starting project in debug mode and look at the output window to see if there are any binding errors
Give this a shot; I believe you have your SelectedValuePath and SelectedValue mixed up:
<ComboBox ItemsSource="{Binding OrderInfoVm.AllCountries}"
SelectedValue="country_code"
DisplayMemberPath="country_name"
SelectedValuePath="{Binding OrderInfoVm.BillingCountry}" />
For Reference:
ItemsSource = Gets or sets a collection used to generate the content of the ItemsControl (ComboBox).
SelectedValue = Gets or sets the value of the SelectedItem, obtained by using SelectedValuePath.
SelectedValuePath = Gets or sets a value that indicates the path used to get the SelectedValue from the SelectedItem.
DisplayMemberPath = Gets or sets a path to a value on the source object to serve as the visual representation of the object.

Resources