gpt4 book ai didi

WPF Master-Details View ,带 Listbox 和 Combobox 带绑定(bind)

转载 作者:行者123 更新时间:2023-12-01 12:01:13 26 4
gpt4 key购买 nike

几天来我一直在四处寻找问题的答案,但找不到解决方案。

问题在于组合框使用先前选择的用户更新了用户类中的测试对象。<​​/p>

即您选择 user2 并且 user2 具有 test2,然后您选择具有 test5 的 user5。现在如果你再次选择 user2,它会显示它有 test5。

这是一些代码。我有两个类用户和测试。每个都有两个 ObservableCollection。这就是我设置它们的方式:

public class User
{
public string Name { get; set; }
public int test { get; set; }
public test userTest { get; set; }
}

public class test
{
public int ID { get; set; }
public String Name { get; set; }
}

public class ListOfTests:ObservableCollection<test>
{
public ListOfTests()
{
for (int i = 0; i < 4; i++)
{
test newTest = new test();
newTest.ID = i;
newTest.Name = "Test " + i;
Add(newTest);
}
}
}

public class ListOfUsers: ObservableCollection<User>
{
public ListOfUsers()
{
ListOfTests testlist = new ListOfTests();
for (int i = 0; i < 10; i++)
{
User newUser = new User();
newUser.Name = "User " + i;
newUser.ID = i;
newUser.userTest = testlist[i];
Add(newUser);
}
}
}

XAML 是:

<Window x:Class="ComboboxTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ComboboxTest"
Title="Window1" Height="300" Width="300">
<StackPanel x:Name="SP1">
<StackPanel.Resources>
<local:ListOfTests x:Key="ListOfTests" />
</StackPanel.Resources>
<ListBox ItemsSource="{Binding}" DisplayMemberPath="Name" IsSynchronizedWithCurrentItem="True"/>
<TextBox Text="{Binding Path=Name}" Foreground="Black" />
<TextBox Text="{Binding Path=userTest}" />
<ComboBox SelectedItem="{Binding Path=userTest}"
SelectedValue="{Binding Path=userTest.ID}"
ItemsSource="{Binding Source={StaticResource ListOfTests}}"
DisplayMemberPath="Name"
SelectedValuePath="ID"

Foreground="Black" />
</StackPanel>

现在,如果我将 SelectedItem 上的 Binding 更改为“{Binding Path=userTest, Mode=OneWay}”,那么它会起作用,但我无法手动更改它。

这是一个更有趣的想法...如果我以 .Net 4.0 (VS2010) 为目标那么它工作正常...

谁能帮我找到解决这个问题的方法?

最佳答案

如果我能理解您的问题,听起来好像是当属性值发生变化时 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 事件,并根据需要更新任何受影响的绑定(bind)。这应该会导致 ComboBox 中的选定项目变回 user2 的测试。

更新:好的,我想我成功了。我认为您在发布的内容中遗漏了部分代码(例如 WindowDataContext 是什么),但这是我的工作:

我创建了一个名为 ViewModel 的类,它被设置为主 WindowDataContext。这是它的代码:

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 的一个实例被用作 ComboBoxItemsSource,而另一个实例用于构建用户列表。我不确定这是否是问题的一部分,但最好只列出一个测试列表。

Window 的 XAML 如下:

<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 属性。它绑定(bind)到 ListBox.SelectedItemComboBox.SelectedItem 绑定(bind)到 CurrentUser.UserTest。这将更改 ComboBox 中的选择,以表示在 ListBox 中选择的用户的测试。

我使用 Visual Studio 2008 SP1 完成了所有这些工作,因此希望它也适用于您。如果您在执行此操作时遇到任何问题,请告诉我,我会尽力而为。

关于WPF Master-Details View ,带 Listbox 和 Combobox 带绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1214861/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com