Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I have overrided the method OnSourceInitialized and I have one problem. After populating my combobox with source property from c# code I want automatically an item will appear selected in the combobox when a page is loaded (default value) but for some reason after onsourceinitialized method, the combobox selected item change to null.
First of all, very good explanation thanks.
I'll try to explain more and I post some code following. I have made some modifications but without success. It continues not working.
My goal is to show a default value selected in the combobox when window is loaded and it is shown.
Initially, when user selects a option in menu application I do the following:
WinMain.xaml.cs:
namespace MyNamespace
public partial class WinMain : Window
private void mnuItemPreferences_Click(object sender, RoutedEventArgs e)
MyNamespace.Windows.EditPreferences editPrefWnd =
new MyNamesapece.Windows.EditPreferences();
// Modal window that I want to open with default values in comboboxes
editPrefWnd.ShowDialog();
} // end WinMain class
} // end namespace
EditPreferences.xaml.cs:
namespace MyNamespace.Windows
public partial class EditPreferences : Window
// My constructor
public EditPreferences()
// Handlers
Loaded += PreferencesWindow_Loaded;
Closing += PreferencesWindow_Closing;
InitializeComponent();
if (System.Environment.OSVersion.Version.Major < 6)
this.AllowsTransparency = true;
_bolAeroGlassEnabled = false;
_bolAeroGlassEnabled = true;
this.ShowInTaskbar = false;
} // end constructor
private void PreferencesWindow_Loaded(object sender,
System.Windows.RoutedEventArgs e)
if (this.ResizeMode != System.Windows.ResizeMode.NoResize)
//this work around is necessary when glass is enabled and the
//window style is None which removes the chrome because the
//resize mode MUST be set to CanResize or else glass won't display
this.MinHeight = this.ActualHeight;
this.MaxHeight = this.ActualHeight;
this.MinWidth = this.ActualWidth;
this.MaxWidth = this.ActualWidth;
// Populate comboboxes
cbLimHorasExtra.ItemsSource = Accessor.GetLimHorasExtraSorted();
cbFracHorasExtra.ItemsSource = Accessor.GetFracHorasExtraSorted();
// Fill controls with default values (see below)
FillControls();
// Install other handlers
rdoBtnOTE.Checked += this.rdoBtnOTE_Checked;
rdoBtnOTM.Checked += this.rdoBtnOTM_Checked;
chkboxRestrict.Checked += this.chkboxRestrict_Checked;
expAdditionalDetails.Collapsed +=
this.expAdditionalDetails_Collapsed;
expAdditionalDetails.Expanded += this.expAdditionalDetails_Expanded;
cbLimHorasExtra.SelectionChanged +=
this.cbLimHorasExtra_SelectionChanged;
cbFracHorasExtra.SelectionChanged +=
this.cbFracHorasExtra_SelectionChanged;
protected override void OnSourceInitialized(System.EventArgs e)
base.OnSourceInitialized(e);
if (_bolAeroGlassEnabled == false)
//no aero glass
this.borderCustomDialog.Background =
System.Windows.SystemColors.ActiveCaptionBrush;
this.tbCaption.Foreground =
System.Windows.SystemColors.ActiveCaptionTextBrush;
this.borderCustomDialog.CornerRadius =
new CornerRadius(10, 10, 0, 0);
this.borderCustomDialog.Padding =
new Thickness(4, 0, 4, 4);
this.borderCustomDialog.BorderThickness =
new Thickness(0, 0, 1, 1);
this.borderCustomDialog.BorderBrush =
System.Windows.Media.Brushes.Black;
//aero glass
if (VistaAeroAPI.ExtendGlassFrame(this,
new Thickness(0, 25, 0, 0)) == false)
//aero didn't work make window without glass
this.borderCustomDialog.Background =
System.Windows.SystemColors.ActiveCaptionBrush;
this.tbCaption.Foreground =
System.Windows.SystemColors.ActiveCaptionTextBrush;
this.borderCustomDialog.Padding =
new Thickness(4, 0, 4, 4);
this.borderCustomDialog.BorderThickness =
new Thickness(0, 0, 1, 1);
this.borderCustomDialog.BorderBrush =
System.Windows.Media.Brushes.Black;
_bolAeroGlassEnabled = false;
private void FillControls()
tblPreferencias tbl_pref = null;
// Obtain data (a record with fields)
// Accessor is a class where I define the methods to
// obtain data of different tables in my database
tbl_pref = Accessor.GetActualPreferencias();
// Only returns one register
if (tbl_pref != null)
rdoBtnOTE.IsChecked = (bool)tbl_pref.OTE;
rdoBtnOTM.IsChecked = (bool)tbl_pref.OTM;
chkboxRestrict.IsChecked =
(bool)tbl_pref.RestriccionHExtraTipoA;
// Here the value assigned is always in the range of the values
// which combo has been populated.
// With one 0 ... 8
// I debbugged it and works.
// selected value (no null) and text gets the correct value I
// want but after OnSourceInitialized method is executed I note
// that for some rease selected value property gets value null
cbLimHorasExtra.Text = tbl_pref.LimiteHorasExtra.ToString();
cbFracHorasExtra.Text =
tbl_pref.FraccionDeMinutosExtra.ToString();
} // end EditPreferences class
} // end namespace
EditPreferences.xaml (I put as example one of the comboboxes):
<Window x:Class="MyNamespace.Windows.EditPreferences"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="EditPreferences" Height="Auto" Width="500"
Background="{x:Null}"
SnapsToDevicePixels="True" SizeToContent="Height"
WindowStartupLocation="CenterScreen"
ResizeMode="NoResize"
WindowStyle="None"
Margin="0,0,0,0"
<ComboBox x:Name="cbLimHorasExtra"
DisplayMemberPath="LimHora"
SelectedValuePath="Id"
SelectedItem="{Binding Path=Id}"
VerticalAlignment="Center"
HorizontalContentAlignment="Right"
Width="50"/>
</Window>
Accessor.cs:
namespace GesHoras.Classes
class Accessor
// This method is used to populate the combobox with its values
// tblLimHorasExtra is a table in my SQL Database
// Its fields are:
// Id : int no null (numbers 1 ... 9)
// LimHora: int no null (numbers 0 ... 8)
public static System.Collections.IEnumerable GetLimHorasExtraSorted()
DataClassesBBDDDataContext dc = new
DataClassesBBDDDataContext();
return (from l in dc.GetTable<tblLimHorasExtra>()
orderby l.LimHora
select new { Id=l.Id, LimHora=l.LimHora });
// tblPreferencias is a table in my SQL Database
// Its fields are:
// Id : int no null
// Descripcion : varchar(50) no null
// OTE : bit no null
// OTM : bit no null
// LimiteHorasExtra : int no null
// FraccionDeMinutosExtra : int no null
// RestriccionHExtraTipoA : bit no null
public static tblPreferencias GetActualPreferencias()
DataClassesBBDDDataContext dc = new
DataClassesBBDDDataContext();
return (from actP in dc.GetTable<tblPreferencias>()
where (actP.Id == 3)
select actP).SingleOrDefault<tblPreferencias>();
} // end class
} // end namespace
The problem I see is that when method fillControls is executed all is ok, selectedvalue and text property for the combobox is correct (I have debbugged it and is correct) but after executing OnSourceInitialized method, selectedvalue property for the combobox gets null value.
Also I note that, when window opens, the comboboxes appear with the default values selected that I want but quickly I see that for some reason their values selected turns to empty in the comboboxes. It's like some event (I think after executing OnSourceMethod because I have debugged and see how it change to null) makes the selected default values that appears ok in the comboboxes turn to empty.
I have tested that comboboxes are populated correctly because once the window is shown I click in the comboboxes and I can see they are populated ok.
EDIT 2
Also I have forced selected index for combobox in fillControls method by doing:
cbLimHorasExtra.SelectedIndex = 1;
but without success...
The combobox is populated with values: 0 to 8 both included.
If the "Id" property in the DataContext
is not an item in the ItemsSource, SelectedItem
will be set to null.
Timing
When InitializeComponent
is called, it parses the XAML which sets the SelectedItem
binding. If the DataContext
is not set, then initially this will be null. Later when DataContext
is set, the binding is re-evaluated. If Id
is in the list at that point, the SelectedItem
is set. Otherwise it is set to null.
Any binding that cannot be evaluated initially during InitializeComponent
is scheduled using the dispatcher to be re-evaluated once all events have fired. Without details on how your DataContext is being set I can't give specifics, but my guess is that one of your binding is getting deferred so your {Binding Path=Id}
binding is evaluated in a dispatcher callback.
A dispatcher callback is not an event - it is a prioritized work queue. If you have this kind of situations your choices are:
Change the bindings so they can be evaluated during initialization
Use a Dispather.BeginInvoke to schedule your own callback to execute after the Binding completes
Let the Binding take care of setting the SelectedItem rather than setting manually in code
Additional notes
Your use of SelectedValueSource
looks suspicious. Your binding to SelectedItem
seems to indicate that each item in the ItemsSource
is an "Id", but your definition of SelectedValueSource
seems to indicate that each item in the ItemsSource
contains an "Id". It is rare to find a data structure where the structure itself is called "Id" by another structure, yet it itself has an "Id" field. Thus I suspect some confusion here. Without seeing your actual data structures I can't say more.
Your use of OnSourceInitialized
also makes it appear you have a misunderstanding. The "Source" in the name of OnSourceInitialized
refers to a "presentation source" such as a Win32 hWnd, not a source of data. The purpose of OnSourceInitialized
is to interact at a low level with the Windows operating system, or to update your application based on where it is being presented. Your use seems completely unrelated to this. I would recommend you stay away from OnSourceInitialized
. Generally the best time to initialize ComboBoxes and such is to just provide it in your view model and let data binding take care of it. As soon as the view model is available the data will be populated with no code required.
Set the SelectedIndex property at the end of your override, by the way, i can't seem to find OnSourceInitialised, only Initialised. But it should still work if you set it at the end of your code.
private void MyListBox_Initialized(object sender, EventArgs e)
// Run some code
if (MyListBox.Items.Count > 0)
MyListBox.SelectedIndex = 0;
I don't have a real answer to your question, but OnSourceInitialized seems to be too early in the initialization process.
Again, I have not tried your exact scenario, but many problems like this one are solved by calling FillControls (i.e. setting the selected item) in the Loaded event instead of earlier.
I have solved it!
The problem was in binding the SelectedItem property in EditPreferences.xaml:
<ComboBox x:Name="cbLimHorasExtra"
DisplayMemberPath="LimHora"
SelectedValuePath="Id"
SelectedItem="{Binding Path=Id}"
VerticalAlignment="Center"
HorizontalContentAlignment="Right"
Width="50"/>
The solution is to change to:
<ComboBox x:Name="cbLimHorasExtra"
DisplayMemberPath="LimHora"
SelectedValuePath="Id"
SelectedItem="Id"
VerticalAlignment="Center"
HorizontalContentAlignment="Right"
Width="50"/>