Если я понимаю ваш вопрос, похоже, что WPF не уведомляется при изменении значения свойства. Вы можете обойти это, реализовав интерфейс INotifyPropertyChanged . Например, класс User
будет выглядеть примерно так:
public class User : INotifyPropertyChanged
{
private string name = string.Empty;
public string Name
{
get { return this.name; }
set
{
this.name = value;
this.OnPropertyChanged("Name");
}
}
private int test = 0;
public int Test
{
get { return this.test; }
set
{
this.test = value;
this.OnPropertyChanged("Test");
}
}
private test userTest = null;
public test UserTest
{
get { return this.userTest; }
set
{
this.userTest = value;
this.OnPropertyChanged("UserTest");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
PropertyChangedEventHandler eh = this.PropertyChangd;
if(null != eh)
{
eh(this, new PropertyChangedEventArgs(propName));
}
}
}
Вероятно, вы должны сделать то же самое для вашего test
класса.
WPF будет следить за событием PropertyChanged
и обновлять любые привязанные привязки по мере необходимости. Это должно привести к тому, что выбранный элемент в ComboBox
вернется к тесту для user2.
Обновление : ОК, думаю, у меня все получилось. Я думаю, что вам не хватает части кода в том, что вы опубликовали (например, что такое DataContext
для Window
), но вот что я получил:
Я создал класс с именем ViewModel
, для которого установлено DataContext
основного Window
. Вот его код:
class ViewModel : INotifyPropertyChanged
{
public ViewModel()
{
for(int i = 0; i < 4; i++)
{
this.tests.Add(new Test()
{
ID = i,
Name = "Test " + i.ToString(),
});
}
for(int i = 0; i < 4; i++)
{
this.users.Add(new User()
{
Name = "User " + i.ToString(),
ID = i,
UserTest = this.tests[i],
});
}
}
private ObservableCollection<User> users = new ObservableCollection<User>();
public IEnumerable<User> Users
{
get { return this.users; }
}
private ObservableCollection<Test> tests = new ObservableCollection<Test>();
public IEnumerable<Test> Tests
{
get { return this.tests; }
}
private User currentUser = null;
public User CurrentUser
{
get { return this.currentUser; }
set
{
this.currentUser = value;
this.OnPropertyChanged("CurrentUser");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propName)
{
var eh = this.PropertyChanged;
if(null != eh)
{
eh(this, new PropertyChangedEventArgs(propName));
}
}
}
Я перенес создание двух списков в код. Одна вещь, которую я заметил в вашем примере, это то, что один экземпляр ListOfTests
использовался как ItemsSource
для ComboBox
, тогда как другой экземпляр использовался для построения ListOfUsers
. Я не уверен, было ли это частью проблемы или нет, но лучше всего иметь один список тестов.
XAML для основного Window
выглядит следующим образом:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="Window1" Height="300" Width="300">
<StackPanel>
<ListBox ItemsSource="{Binding Path=Users}"
SelectedItem="{Binding Path=CurrentUser}"
DisplayMemberPath="Name"
IsSynchronizedWithCurrentItem="True">
</ListBox>
<TextBox Text="{Binding Path=CurrentUser.Name}" />
<TextBox Text="{Binding Path=CurrentUser.UserTest.Name}" />
<ComboBox ItemsSource="{Binding Path=Tests}"
SelectedItem="{Binding Path=CurrentUser.UserTest}"
DisplayMemberPath="Name" />
</StackPanel>
</Window>
Ключом к тому, чтобы все заработало, является свойство CurrentUser
. Он связан с ListBox.SelectedItem
, а ComboBox.SelectedItem
связан с CurrentUser.UserTest
. Это изменит выбор в ComboBox
для представления теста пользователя, выбранного в ListBox
.
У меня все это работает с использованием Visual Studio 2008 SP1, так что, надеюсь, оно будет работать и для вас. Если у вас возникнут какие-либо проблемы с этим, дайте мне знать, и я посмотрю, что я могу сделать.