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实体以所选值更新。

我意识到这已经成为一个很长的问题,但请如果有人能看到我做错了什么?

WPF双向数据绑定列表框无法获得选定值

代码有几个问题:

  1. 在visual studio OUTPUT窗口中有两个绑定错误(当列表框源被定义并包含元素时),原因是SelectedValuePath绑定错误和源类型冲突。以下是我的解决方案。
  2. 数据上下文集合初始化:

    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,
                }
            })
        };
    }
    
  3. Xaml代码:
  4. <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>
    
  5. 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;
    }
    
  6. 因此,每次我选择槽的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.SlotTypeint类型。所以你需要使用SelectedValue属性,而不是SelectedItem
  • 看起来你把SelectedValueSelectedValuePath弄混了,SelectedValue绑定指向数据上下文中的对象,在那里选择的项目的值应该被存储,在这种情况下= slot.SlotType
  • SelectedValuePath -它是所选项目的路径,应该设置为所选值-它是一个静态字符串,不需要绑定任何
  • DisplayMemberPath—如上所述,它是一个静态字符串,指示保存需要显示的值的属性的路径—不需要在这里绑定任何东西