I have a problem with a particular xaml databinding.
I have two listboxes (master-details, so the listboxes have IsSynchronizedWithCurrentItem set to true). I want my viewmodel to know when the selected item on the details listbox changes: I created an int property on my viewmodel class (i.e. we can call this property SelInd)and on the details viewmodel I bind this way:
SelectedIndex="{Binding Mode=OneWayToSource, Path=SelInd}"
I get no errors/exceptions at runtime, but the binding does not trigger: my viewmodel's property does not get updated when the selected item changes. If I change the binding mode to TwoWay everything works fine, but that's not what I need. I need it to work with OneWayToSource (btw the same non-working behaviour applies if I bind SelectedItem to SelectedValue properties).
Why do those bindings do not trigger with OneWayToSource?
Here's a more complete code example, just to get the things clearer:
EDIT: I can't show the real code (NDA) but I'll show here something simpler and similar enough (the Page's DataContext is an instance of the PageViewModel class explained later)
I just need that my viewmodel class's SelInd property should always reflect the value of SelectedIndex in the second ListBox. I have found alternative methods for doing this (Event handler in code-behind or an Attached Behaviour) but right now I'm just curious about WHY it doesn't work with OneWayToSource binding.
<Page>
<ContentControl x:Name="MainDataContext">
<Grid DataContext={Binding Path=Masters}>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Column="0"
SelectionMode="Single"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding }">
<ListBox.ItemContainerStyle>
...
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
....
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Grid.Column="1"
SelectionMode="Single"
SelectedIndex="{Binding Mode=OneWayToSource, ElementName=MainDataContext,Path=DataContext.SelInd}"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Path=Details}">
<ListBox.ItemContainerStyle>
...
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
....
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</ContentControl>
</Page>
Here's a sketch of the view model class
public class PageViewModel{
public ObservableCollection<MasterClass> Masters {get;set;}
public int SelInd {get;set;}
....
}
And here's MasterClass, it just holds a name and a list of details
public class MasterClass{
public ObservableCollection<DetailsClass> Details {get;set;}
public String MasterName {get;set;}
....
}
I think in your case, you must use the mode OneWay. By default, you have used mode TwoWay.
Quote from MSDN about TwoWay:
TwoWay binding causes changes to either the source property or the target property to automatically update the other. This type of binding is appropriate for editable forms or other fully-interactive UI scenarios. Most properties default to OneWay binding, but some dependency properties (typically properties of user-editable controls such as the Text property of TextBox and the IsChecked property of CheckBox) default to TwoWay binding. A programmatic way to determine whether a dependency property binds one-way or two-way by default is to get the property metadata of the property using GetMetadata and then check the Boolean value of the BindsTwoWayByDefault property.
Mode OneWay, that you need:
OneWay binding causes changes to the source property to automatically update the target property, but changes to the target property are not propagated back to the source property. This type of binding is appropriate if the control being bound is implicitly read-only. For instance, you may bind to a source such as a stock ticker or perhaps your target property has no control interface provided for making changes, such as a data-bound background color of a table. If there is no need to monitor the changes of the target property, using the OneWay binding mode avoids the overhead of the TwoWay binding mode.
Mode OneWayToSource:
OneWayToSource is the reverse of OneWay binding; it updates the source property when the target property changes. One example scenario is if you only need to re-evaluate the source value from the UI.
Below is a diagram for a better understanding of the:
Okay, then I'll show you an example that works for me. Perhaps it will be useful to you.
XAML
<Window x:Class="SelectedIndexHelp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SelectedIndexHelp"
Title="MainWindow" Height="350" Width="525"
ContentRendered="Window_ContentRendered"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<local:SelectedIndexClass x:Key="SelectedIndexClass" />
</Window.Resources>
<Grid DataContext="{StaticResource SelectedIndexClass}">
<ListBox x:Name="MyListBox"
BorderThickness="1"
Width="200" Height="200"
BorderBrush="#CE5E48"
DisplayMemberPath="Name"
Background="AliceBlue"
SelectedIndex="{Binding MySelectedIndex, Mode=OneWayToSource}" />
<Label Name="SelectedIndex" VerticalAlignment="Top"
Content="{Binding MySelectedIndex}"
ContentStringFormat="SelectedIndex: {0}"
Width="100" Height="30" Background="Lavender" />
</Grid>
</Window>
Code behind
public partial class MainWindow : Window
{
public class Person
{
public string Name
{
get;
set;
}
public int Age
{
get;
set;
}
}
private ObservableCollection<Person> DataForListBox = new ObservableCollection<Person>();
public MainWindow()
{
InitializeComponent();
}
private void Window_ContentRendered(object sender, EventArgs e)
{
DataForListBox.Add(new Person()
{
Name = "Sam",
Age = 22,
});
DataForListBox.Add(new Person()
{
Name = "Nick",
Age = 21,
});
DataForListBox.Add(new Person()
{
Name = "Cris",
Age = 25,
});
DataForListBox.Add(new Person()
{
Name = "Josh",
Age = 36,
});
DataForListBox.Add(new Person()
{
Name = "Max",
Age = 32,
});
DataForListBox.Add(new Person()
{
Name = "John",
Age = 40,
});
MyListBox.ItemsSource = DataForListBox;
MyListBox.Focus();
}
}
public class SelectedIndexClass
{
private int? mySelectedIndex = 0;
public int? MySelectedIndex
{
get
{
return mySelectedIndex;
}
set
{
mySelectedIndex = value;
}
}
}
Output
In this example, there is a class of data - Person, these data for ListBox. And the class SelectedIndexClass (DataContext), which contains the property MySelectedIndex, which is a parameter of binding OneWayToSource.
Edit: I'm glad you figured out with the problem. I'll try to explain by their example, why are you not working with ElementName case.
So, let's say we have this code:
<ContentControl x:Name="MainDataContext">
<Grid x:Name="MainGrid" DataContext="{StaticResource SelectedIndexClass}">
<ListBox x:Name="MyListBox"
BorderThickness="1"
Width="200" Height="200"
BorderBrush="#CE5E48"
DisplayMemberPath="Name"
Background="AliceBlue"
SelectedIndex="{Binding Path=DataContext.MySelectedIndex, Mode=OneWayToSource, ElementName=MainDataContext}" />
<Label Name="SelectedIndex" VerticalAlignment="Top"
Content="{Binding MySelectedIndex}"
ContentStringFormat="SelectedIndex: {0}"
Width="100" Height="30" Background="Lavender" />
</Grid>
</ContentControl>
As you probably understand, it will not work.
DataContext set on a specific node of the visual tree, all items below (in the visual tree) inherit it. This means that the DataContext will be working since the Grid and below the visual tree. Therefore, the following code will work:
<ContentControl x:Name="MainDataContext">
<Grid x:Name="MainGrid" DataContext="{StaticResource SelectedIndexClass}">
<ListBox x:Name="MyListBox"
BorderThickness="1"
Width="200" Height="200"
BorderBrush="#CE5E48"
DisplayMemberPath="Name"
Background="AliceBlue"
SelectedIndex="{Binding Path=DataContext.MySelectedIndex, Mode=OneWayToSource, ElementName=MainGrid}" />
<Label Name="SelectedIndex" VerticalAlignment="Top"
Content="{Binding MySelectedIndex}"
ContentStringFormat="SelectedIndex: {0}"
Width="100" Height="30" Background="Lavender" />
</Grid>
</ContentControl>
And also, it will work if the name of the point MyListBox. Usually, when set the DataContext, the element name is passed.
Well, I found a way to make it work. I just removed the data-context "indirection" so I don't have to use ElementName in my bindings, and it started working. The working xaml example is:
<Page>
<ContentControl >
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Column="0"
SelectionMode="Single"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Masters }">
<ListBox.ItemContainerStyle>
...
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
....
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Grid.Column="1"
SelectionMode="Single"
SelectedIndex="{Binding Mode=OneWayToSource, Path=SelInd}"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Path=Masters/Details}">
<ListBox.ItemContainerStyle>
...
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
....
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</ContentControl>
</Page>
Now, if someone knows exactly WHY the binding using ElementName does not work, I'd like to know it :)
Related
The Classes
public class TreeDiagram : INotifyPropertyChanged
{
public string CategoryName
{...}
public ObservableCollection<ImageInfo> DiagramsTRV
{...}
public class ImageInfo : INotifyPropertyChanged
{
public string Category
{ ...}
public override string ToString()
{
return DisplayName;
}
public string DisplayName
{...}
public ObservableCollection<TreeDiagram> TreeDiagrams {...}
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical">
<TextBlock Text="Binding"/>
<TreeView x:Name="trvDiagrams" Width="300" Height="400" ItemsSource="{Binding TreeDiagrams}" HorizontalAlignment="Left">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="x:Type local:TreeDiagram" ItemsSource="{Binding DiagramsTRV, UpdateSourceTrigger=PropertyChanged}">
<TextBlock Width="250" Text="{Binding CategoryName, UpdateSourceTrigger=PropertyChanged}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
<StackPanel Orientation="Vertical">
<TextBox Text="No Binding"/>
<TreeView x:Name="trvNoBind" Width="300" Height="400" HorizontalAlignment="Right">
</TreeView>
</StackPanel>
</StackPanel>
</StackPanel>
If I use binding, the Category Name is displayed, the The TreeDiagram ToString() is never called and the dropdown items are blank.
If I load the tree programmatically with the same data - everything is fine.
But for a variety of reasons, I need to use binding.
I have tried an IValueConverter to take the collection of objects and return a collection of strings - no joy.
Any suggestions as to what I am doing wrong?
Your template is incomplete. You must define a template for the child nodes too. You must either set the HierarchicalDataTemplate.ItemsTemplate property accordingly or define an implicit template e.g. in the ResourceDictionary of the TreeView.
You want to display a recursive or hierarchical data structure. Since your structure consists of different data types, you must define a template for each level.
Note that UpdateSourceTrigger.PropertyChanged is the default value of Binding.UpdateSourceTrigger and is therefore not explicitly required.
<TreeView>
<TreeView.Resources>
<!--
Because 'ImageInfo' has no children,
define a 'DataTemplate' (instaed of another 'HierarchicalDataTemplate').
If this 'DataTemplate' wasn't implicit, you would have to explicitly assign it
to the parent's 'HierarchicalDataTemplate.ItemTemplate' property.
-->
<DataTemplate DataType="{x:Type local:TreeDiagram}">
<TextBlock Text="{Binding}" /> <== Force the call to 'object.ToString' by binding to the object itself
</DataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:TreeDiagram}"
ItemsSource="{Binding DiagramsTRV}">
<TextBlock Text="{Binding CategoryName}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
I'm working on a MVVM-project using XAML.
I'm having problems accessing a property of an outer element when operating inside a ListView with an ItemSource binding.
XAML:
<ListView x:Name="BibTexFields" Height="422" ItemsSource="{Binding BibTexFields}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="450">
<TextBlock Foreground="Black" Text="{Binding Field.Name}"/>
<CheckBox HorizontalAlignment="Right" IsChecked="{Binding IsChecked, Mode=TwoWay}" Command="{Binding UpdateFilledFieldsCommand}"/>
BibTexFields is a property from my ViewModel which also is my DataContext. So is UpdateFilledFieldsCommand
XAML:
xmlns:vm="using:StudyConfigurationClient.ViewModels"
mc:Ignorable="d" d:DataContext="{d:DesignInstance vm:CreateStudyViewModel}">
<Grid x:Name="FieldOuter">
<Border BorderBrush="Gray" BorderThickness="2" Margin="0, 0, 5, 0">
ViewModel:
private ObservableCollection<ChosenField> _bibTexFields;
public ObservableCollection<ChosenField> BibTexFields
{
get { return _bibTexFields; }
set
{
_bibTexFields = value;
OnPropertyChanged();
}
}
What I want to do is access the ViewModel from inside the ListView, so that I can make a Command with a binding to the UpdateFilledFieldsCommand property.
I've tried researching the RelativeSource binding, but can't seem to make it work. Nor does trying binding it to the DataContext work.
You can also use ElementName:
<CheckBox HorizontalAlignment="Right" IsChecked="{Binding IsChecked, Mode=TwoWay}" Command="{Binding DataContext.UpdateFilledFieldsCommand, ElementName=BibTexFields}"/>
However, RelativeSource should also work. With a quick search, I found this: How do I use WPF bindings with RelativeSource? It looks fine though I don't know if all the features are present in an UWP app.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I've created a custom control for selecting States in my application, called StateSelector. If I place it in my UserControl and bind the ItemsSource (through a custom property called StateList) it works fine. But using the same binding in a DataTemplate does not work.
Here is my StateSelector.xaml
<UserControl x:Class="MyNamespace.StateSelector"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Local="clr-namespace:MyNamespace"
Height="21" Width="60">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ComboBox Grid.Column="0"
Name="cboState"
SelectedItem="{Binding Path=CurrentState, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
ItemsSource="{Binding Path=StateList, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Code}" />
<TextBlock Text="{Binding Path=Name}" Margin="5,0,0,0" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</UserControl>
Here is my StateSelector.xaml.cs
public class StateSelector : UserControl
{
public ObservableCollection<State> StateList
{
get { return (ObservableCollection<State>)GetValue(StateListProperty); }
set { SetValue(StateListProperty, value); }
}
public static readonly DependencyProperty StateListProperty =
DependencyProperty.Register("StateList", typeof(ObservableCollection<State>), typeof(StateSelector));
public State CurrentState
{
get{ return (State)GetValue(CurrentStateProperty); }
set{ SetValue(CurrentStateProperty, value); }
}
public static DependencyProperty CurrentStateProperty =
DependencyProperty.Register("CurrentState", typeof(State), typeof(StateSelector));
/// <summary>
/// Default constructor for StateSelector
/// </summary>
public StateSelector()
{
InitializeComponent();
}
}
Then in the containing UserControl's Constructor I populate an ObservableCollection with State objects.
Here is MyDisplay.xaml.cs
public class MyDisplay : UserControl
{
private static DependencyProperty StateListProperty =
DependencyProperty.Register("StateList", typeof(ObservableCollection<State>), typeof(RateTableDisplay));
public ObservableCollection<State> StateList
{
get{ return (ObservableCollection<State>)GetValue(StateListProperty); }
set{ SetValue(StateListProperty, value); }
}
// Code to define SourceObject as seen in following XAML omitted
public MyDisplay()
{
InitializeComponent();
StateManager stateManager = new StateManager();
StateList = new ObservableCollection<State>(stateManager.GetAll(Context));
}
}
In the XAML of MyDisplay I have a section that uses the StateSelector as is and another that uses it in a DataTemplate.
Here is MyDisplay.xaml
<UserControl x:Class="MyNamespace.MyDisplay"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:Local="clr-namespace:MyNamespace"
Height="Auto" Width="Auto"
Name="_this"
DataContext="{Binding ElementName=_this, Path=SourceObject}">
<UserControl.Resources>
<ResourceDictionary>
<DataTemplate x:Key="OriginStateCellTemplate">
<Local:StateSelector StateList="{Binding ElementName=_this, Path=StateList}" />
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<!-- Unrelated XAML omitted -->
<!-- The StateSelector below gets populated properly -->
<StackPanel>
<Local:StateSelector Grid.Column="3" StateList="{Binding ElementName=_this, Path=StateList}" x:Name="cmbMasterOriginState" />
</StackPanel>
<!-- More Unrelated XAML omitted -->
<!-- The StateSelector below does not get populated at all -->
<StackPanel>
<ListView Height="610">
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn x:Name="origStateCol" Width="85" CellTemplate="{StaticResource OriginStateCellTemplate}">
<GridViewColumnHeader Click="header_Click" Tag="OriginState">Origin State</GridViewColumnHeader>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</UserControl>
I've tried different ways to bind the StateList such as these:
StateList="{Binding Path=StateList, Source={x:Reference _this}}"
StateList="{Binding Path=StateList, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
But no such luck. I can't figure out why the ItemsSource is not being populated in the DataTemplate example. It works fine outside of the DataTemplate. I'm not getting any binding errors in the Output of Debug in Visual Studio either.
When searching I found quite a few related issues but they all seemed to be trying to use a general DataContext defined in the top UserControl element. I'm specifically trying to use a property of the UserControl itself.
Any ideas?
Implement INotifyPropertyChanged in your UserControl and then create properties for StateList and then on the setter raise the property changed event provided by the INotifyPropertyChanged.
I have the following xaml:
<UserControl.Resources>
<sivm:Locator x:Key="viewModelLocator" ModelType="{x:Type ViewModels:RateVSConcentrationViewModel}"/>
</UserControl.Resources>
<UserControl.DataContext>
<Binding Path="ViewModel" Source="{StaticResource viewModelLocator}"/>
</UserControl.DataContext>
...
<ComboBox Grid.Column="0" Grid.Row="1" Height="20" VerticalAlignment="Top" ItemsSource="{Binding Chambers}" > <!--SelectedItem="{Binding SelectedChamber}">-->
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ChamberName}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Chambers is an ObservableCollection of objects that contains a property called ChamberName which I want displayed in the combobox.
In the ViewModel I have the following code:
foreach (var chamber in chambers)
{
Chambers.Add(chamber);
}
OnPropertyChanged(() => Chambers);
But when this code executes the combobox is not updated. I have used this way to do a lot of databinding but I can't get this to work.
Can someone see what I am doing wrong here?
You may need to set the relativesource on your textblock, try modifying the binding on the Text property of your textblock to the following:
{Binding DataContext.ChamberName, RelativeSource={RelativeSource AncestorType=ComboBox}}
And as nit said above, always check for binding errors, they will put you on the right path.
You should adjust the property binding as follows:
<ComboBox ItemsSource="{Binding Path=ViewModel.Chambers, Source={StaticResource viewModelLocator}}" >
I got it to work doing this:
<ComboBox DisplayMemberPath="ChamberName" Grid.Column="0" Grid.Row="1" Height="20" VerticalAlignment="Top" ItemsSource="{Binding Chambers}"> <!--SelectedItem="{Binding SelectedChamber}">-->
I have a combo box that is not working as I expect at runtime. I can use the mouse to expand the drop-down window, but clicking an item does not seem to select it. The dropdown goes away, but the selection is not changed. The same control seems to work as expected using the keyboard. Arrow up/down changes the selection. I can use the arrow keys to choose and enter to select to change the value as well.
How do I get clicking to select an item?
<DataTemplate DataType="{x:Type myType}">
<Border ...>
<Grid x:Name="upperLayout">
<Grid x:Name="lowerLayout">
<ComboBox x:Name="combo"
Grid.Column="2"
ItemsSource="{Binding Things}"
SelectedItem="{Binding SelectedThing}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</Grid>
</Border>
</DataTemplate>
I can't really tell what's wrong from your code however, I'd strongly suggest you to use Snoop to debug your controls (http://snoopwpf.codeplex.com/)
By holding Ctrl+Shift and pointing the mouse where you ComboBox is supposed to grab the input you would instantly find out who is having the focus instead of your combo box.
You can even change the value of a property, really your best friend for debugging your templates !
EDIT
I'm afraid but the code you've posted works for me:
<Window x:Class="WpfApplication6.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication6="clr-namespace:WpfApplication6"
Title="MainWindow"
Width="525"
Height="350">
<Window.Resources>
<DataTemplate x:Key="myTemplate" DataType="{x:Type wpfApplication6:MyType}">
<Border>
<Grid x:Name="upperLayout">
<Grid x:Name="lowerLayout">
<ComboBox x:Name="combo"
Grid.Column="0"
ItemsSource="{Binding Path=Things}"
SelectedItem="{Binding Path=SelectedThing}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type wpfApplication6:MyThing}">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</Grid>
</Border>
</DataTemplate>
</Window.Resources>
<Grid x:Name="grid">
<ContentControl x:Name="content" ContentTemplate="{StaticResource myTemplate}" Margin="58,79,71,40" />
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
MyType type = new MyType()
{
Things = new List<MyThing>() {new MyThing() {Name = "aaa"}, new MyThing() {Name = "bbb"}}
};
content.Content = type;
}
}
public class MyType
{
public MyThing SelectedThing { get; set; }
public List<MyThing> Things { get; set; }
}
public class MyThing
{
public string Name { get; set; }
}
Maybe something else is screwing it such as a style with no key or whatever, post more of your code you're having a problem with.
Root cause was that another developer had implemented some code that changed the focus on the preview mouse down event. This code was updated to have the desired behavior without modifying focus and the combo box now works as expected. The information needed to diagnose was not in the original question (can't publish it all...).