C# WPF双向数据绑定列表框到WPF can中的模型';无法获取所选值
我正在WPF中努力进行数据绑定,在搜索了各个方面后,我仍然看不到我缺少了什么,无法使用列表中的选定项更新模型。 我有两个实体,一个Slot和一个SlotTypeC# WPF双向数据绑定列表框到WPF can中的模型';无法获取所选值,c#,wpf,xaml,data-binding,listbox,C#,Wpf,Xaml,Data Binding,Listbox,我正在WPF中努力进行数据绑定,在搜索了各个方面后,我仍然看不到我缺少了什么,无法使用列表中的选定项更新模型。 我有两个实体,一个Slot和一个SlotType public class Slot : BindableObject, INotifyPropertyChanged { private int slotID; public int SlotID { get { return slotID; } set {
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; }
}
最后,在我的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的文本框放入其中,该文本框可以工作并更新回我的模型。我在listbox上尝试了多种绑定格式,可以获得要显示的SlotTypes列表,但无法使用所选值更新Slot实体
我意识到这已经成为一个很长的问题,但请如果有人能看到我做错了什么 我可以看出这里有很多错误,首先,这就是您的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.Data错误:40:BindingExpression路径错误:“类型”
在“对象”“插槽”(HashCode=62085918)上找不到属性。
BindingExpression:Path=slot.Type;DataItem='SlotWithTypes'
(HashCode=23184054);目标元素是“ListBox”
(Name='lstSlotTypes');目标属性为“SelectedItem”(类型
“对象”)System.Windows.Data错误:40:BindingExpression路径
错误:“对象”上未找到“SlotTypeID”属性
''ObservableCollection'1'(HashCode=58050239')。
BindingExpression:Path=slotTypes.SlotTypeID;DataItem='SlotWithTypes'
(HashCode=23184054);目标元素是“ListBox”
(Name='lstSlotTypes');目标属性为“SelectedValue”(类型
'对象')
如你所见,已经有了一些信息
现在,您的xaml有什么问题:
类没有Slot
属性,只有Type
属性SlotType
- 您无法绑定到
的slot.SlotType
,因为SelectedItem
保存了SelectedItem
中的整个选定对象-在这种情况下,是ItemsSource
类,而绑定属性SlotType
的类型是slot.SlotType
。因此,在这种情况下,您需要使用int
属性,而不是SelectedValue
SelectedItem
- 看起来您将
与SelectedValue
相混淆,SelectedValuePath
绑定指向datacontext中存储所选项目值的对象,在这种情况下=SelectedValue
slot.SlotType
- SelectedValuePath-应将选定项上的路径设置为选定值-它是一个静态字符串,无需绑定任何内容
- DisplayMemberPath-如上所述,它是一个静态字符串,指示持有需要显示的值的属性的路径-无需在此处绑定任何内容
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,
}
})
};
}
private void InitDataContext()
{
DataContext=新的SlotWithTypes
{
插槽=新插槽(),
slotTypes=新的ObservableCollection(新列表
{
新SlotType
{
SlotTypeDesc=“Bla Bla 1”,
SlotTypeID=1,
},
新SlotType
{
SlotTypeDesc=“Bla Bla 2”,
SlotTypeID=2,
}
})
};
}
<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>
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;
}
publicobservableCollection slotTypes{get;set;}
公共插槽
{
获取{return\u slot;}
设置
{
_槽=值;
OnPropertyChanged();
}
}
public int SelectedSlotType
{
获取{return\u selectedSlotType;}
设置
{
_selectedSlotType=值;
OnPropertyChanged();
UpdateSlot(SelectedSlotType);
}
}
私有void UpdateSlot(int-selectedSlotType)
{
slot.SlotType=selectedSlotType;
}
关于,逻辑是什么?1.打开窗口时是否有项目列表?2.列表框中是否有任何项目?A您确定,在SelectedValuePath和DisplayMemberPath中需要绑定吗?:)这里一定有一些属性名称。非常感谢Alek,这是一个非常好的答案,有这么多信息。@user5466211只是为了好玩,看看这个。我希望它能帮你一点忙。@Noctis谢谢,非常有帮助,我已经搜索了很久,找不到像Alek的答案和你的文章那样有帮助的东西。@Golik谢谢你的努力,你是对的,我的xaml全错了
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;
}