WPF双向数据绑定列表框无法获得选定值
本文关键字:数据绑定 列表 WPF | 更新日期: 2023-09-27 18:18:32
我正在努力与WPF中的数据绑定进行搜索,我仍然看不到我缺少什么来获得模型以从列表中选择项目更新。我有两个实体一个Slot和一个SlotType
public class Slot : BindableObject, INotifyPropertyChanged
{
private int slotID;
public int SlotID
{
get { return slotID; }
set
{
if (slotID != value)
{
slotID = value;
RaisePropertyChanged("SlotID");
}
}
}
private string user;
public string SlotUser
{
get { return user; }
set
{
if (user != value)
{
user = value;
RaisePropertyChanged("SlotUser");
}
}
}
private int slotUserID;
public int SlotUserID
{
get { return slotUserID; }
set
{
if (slotUserID != value)
{
slotUserID = value;
RaisePropertyChanged("SlotUserID");
}
}
}
private int slotType;
public int SlotType
{
get { return slotType; }
set
{
if (slotType != value)
{
slotType = value;
RaisePropertyChanged("SlotType");
}
}
}
private DateTime slotStartDateTime;
public DateTime SlotStartDateTime
{
get { return slotStartDateTime; }
set
{
if (slotStartDateTime != value)
{
slotStartDateTime = value;
RaisePropertyChanged("SlotStartDateTime");
}
}
}
public class SlotType : BindableObject, INotifyPropertyChanged
{
private int slotTypeID;
public int SlotTypeID
{
get { return slotTypeID; }
set
{
if (slotTypeID != value)
{
slotTypeID = value;
RaisePropertyChanged("SlotTypeID");
}
}
}
private string slotTypeDesc;
public string SlotTypeDesc
{
get { return slotTypeDesc; }
set
{
if (slotTypeDesc != value)
{
slotTypeDesc = value;
RaisePropertyChanged("SlotTypeDesc");
}
}
}
public override string ToString()
{
return SlotTypeDesc;
}
}
然后创建一个包含这两个类的类,并将我的窗口上下文设置为这个类。
public class SlotWithTypes
{
public ObservableCollection<SlotType> slotTypes { get; set; }
public Slot slot { get; set; }
}
从我的主窗口,我测试,如果需要打开一个新的窗口,显示槽类型的列表,供用户选择哪个类型是相关的插槽创建。
Slot slot = new Slot();
slot.SlotStartDateTime = item.SlotStartDateTime;
if (item.SlotType == 0)
{
SlotWithTypes swtype = new SlotWithTypes();
swtype.slotTypes = slotTypes;
swtype.slot = slot;
SelectSlotType stype = new SelectSlotType();
stype.DataContext = swtype;
stype.ShowDialog();
}
最后在XAML中我有一个列表框
<Grid>
<ListBox Name="lstSlotTypes"
HorizontalAlignment="Left"
Height="200"
Margin="0,10,0,0"
VerticalAlignment="Top"
Width="194"
ItemsSource="{Binding slotTypes}"
SelectedItem="{Binding Path=slot.Type, Mode=TwoWay}"
SelectedValue="{Binding slotTypes.SlotTypeID, Mode=TwoWay}"
SelectedValuePath="{Binding slot.Type, Mode=TwoWay}"
DisplayMemberPath="{Binding slotTypes.SlotTypeDesc}"
SelectionChanged="lstSlotTypes_SelectionChanged">
</ListBox>
<TextBox HorizontalAlignment="Left"
Height="23"
Margin="10,246,0,0"
TextWrapping="Wrap"
Text="{Binding slot.SlotStartDateTime, Mode=TwoWay}"
VerticalAlignment="Top"
Width="74"/>
</Grid>
为了测试,我放入一个绑定到slotstartdatetime的文本框,它可以工作并更新回我的模型。我已经在列表框上尝试了各种绑定格式,并且可以获得我的SlotTypes列表来显示put,无法获得Slot实体以所选值更新。
我意识到这已经成为一个很长的问题,但请如果有人能看到我做错了什么?
代码有几个问题:
- 在visual studio OUTPUT窗口中有两个绑定错误(当列表框源被定义并包含元素时),原因是SelectedValuePath绑定错误和源类型冲突。以下是我的解决方案。
-
数据上下文集合初始化:
private void InitDataContext() { DataContext = new SlotWithTypes { slot = new Slot(), slotTypes = new ObservableCollection<SlotType>(new List<SlotType> { new SlotType { SlotTypeDesc = "Bla Bla 1", SlotTypeID = 1, }, new SlotType { SlotTypeDesc = "Bla Bla 2", SlotTypeID = 2, } }) }; }
Xaml代码: <Grid> <ListBox Name="lstSlotTypes" HorizontalAlignment="Left" Height="200" Margin="0,10,0,0" VerticalAlignment="Top" Width="194" ItemsSource="{Binding slotTypes}" SelectedValue="{Binding SelectedSlotType, Mode=TwoWay}" SelectedValuePath="SlotTypeID" DisplayMemberPath="SlotTypeDesc" SelectionChanged="lstSlotTypes_SelectionChanged"> </ListBox></Grid>
SlotWithTypes代码:
public ObservableCollection<SlotType> slotTypes { get; set; } public Slot slot { get { return _slot; } set { _slot = value; OnPropertyChanged(); } } public int SelectedSlotType { get { return _selectedSlotType; } set { _selectedSlotType = value; OnPropertyChanged(); UpdateSlot(SelectedSlotType); } } private void UpdateSlot(int selectedSlotType) { slot.SlotType = selectedSlotType; }
因此,每次我选择槽的SlotType属性将被更改并定义为新值。
认为,
我可以看到这里有很多错误,首先,这就是您的xaml应该看起来像得到这个工作:
<ListBox Name="lstSlotTypes" HorizontalAlignment="Left" Height="200" Margin="0,10,0,0" VerticalAlignment="Top" Width="194"
ItemsSource="{Binding slotTypes}"
SelectedValue="{Binding Path=slot.SlotType}"
SelectedValuePath="SlotTypeID"
DisplayMemberPath="SlotTypeDesc" >
</ListBox>
现在,当您不知道哪些绑定不起作用时,在大多数情况下,这是因为在输出窗口中可见的绑定错误,它可能非常有用,所以每次都要查看那里。例如,在您的xaml中,这就是输出窗口显示的内容:
System.Windows。数据错误:40:BindingExpression路径错误:'Type'在'对象''槽' (HashCode=62085918)'上找不到属性。BindingExpression:路径= slot.Type;DataItem = ' SlotWithTypes '(HashCode = 23184054);目标元素是"ListBox"(Name = ' lstSlotTypes ');目标属性是'SelectedItem' (typeSystem.Windows.Data错误:40:BindingExpression路径错误:'SlotTypeID'属性在'object'上找不到"ObservableCollection‘1’(HashCode = 58050239)"。BindingExpression:路径= slotTypes.SlotTypeID;DataItem = ' SlotWithTypes '(HashCode = 23184054);目标元素是"ListBox"(Name = ' lstSlotTypes ');目标属性是'SelectedValue'(类型"对象")
如你所见,这里已经有一些信息了。
现在你的xaml:
有什么问题?-
Slot
类没有Type
属性,只有SlotType
属性 - 你不能将
SelectedItem
绑定到slot.SlotType
,因为SelectedItem
持有来自ItemsSource
的整个选定对象-在这种情况下是SlotType
类,而绑定属性slot.SlotType
是int
类型。所以你需要使用SelectedValue
属性,而不是SelectedItem
- 看起来你把
SelectedValue
和SelectedValuePath
弄混了,SelectedValue
绑定指向数据上下文中的对象,在那里选择的项目的值应该被存储,在这种情况下=slot.SlotType
- SelectedValuePath -它是所选项目的路径,应该设置为所选值-它是一个静态字符串,不需要绑定任何
- DisplayMemberPath—如上所述,它是一个静态字符串,指示保存需要显示的值的属性的路径—不需要在这里绑定任何东西