WPF列表框绑定

7

我有一个医生对象,其中一个属性是诊所的 ObservableList。它被用于在窗口中显示医生的详细信息。我可以将单个属性绑定到 TextBoxComboBox 控件,但是我无法将诊所列表绑定到我的 ListBox

以下是我的 ListBox 的 XAML:

<ListBox Height="318" 
 HorizontalAlignment="Left" 
 Margin="422,0,0,0" 
 Name="lbClinic" 
 VerticalAlignment="Top" 
 Width="158" 
 SelectedValue="{Binding ClinicID, Path=Clinics, Mode=TwoWay, 
                          UpdateSourceTrigger = PropertyChanged}"
 SelectedValuePath="ClinicID" 
 DisplayMemberPath="Name"
 ItemsSource="{Binding DataContext.ClinicList, 
                          ElementName = PhysicianInfoLookup, Mode = OneWay}" 
 SelectionMode="Multiple" />

Listbox可以正确地填充来自ClinicList的项目,ClinicList是所有可能诊所的列表。然而,我无法绑定来自医生对象的诊所列表,以便其项目在Listbox中被选中。我还希望反过来,如果取消选择一个项目,则医生对象中的ObservableList会相应更改。如何将我的医生对象中的Clinics的ObservableList双向绑定到我的Listbox中的Clinics(clinic对象的ObservableList)?谢谢。

您的意思是ListBox显示所有诊所的列表,当前医生的诊所会被选中吗? - NestorArturo
不,Listbox 显示所有诊所的列表。我想将医生对象属性中的诊所列表绑定到 Listbox,以便选择这些诊所。 - Mike Malter
只需查看VS输出,它会告诉您绑定出了什么问题。 - Snowbear
我不理解你的回答,能否请您详细说明一下?谢谢。 - Mike Malter
3个回答

13

Mike,你的绑定存在几个问题。以下是一个完整的示例,演示了一种实现你想要的功能的方法。(我认为)

视图:

<Page.Resources>
    <ViewModel:Physician x:Key="physician"/>
</Page.Resources>
<StackPanel DataContext="{StaticResource physician}" >
    <TextBlock Text="{Binding Name}" Background="Orange"/>
    <TextBlock Text="Works in:"/>
    <ListBox ItemsSource="{Binding Clinics}" 
             SelectedValue="{Binding SelectedClinicId}" 
             SelectedValuePath="Id" DisplayMemberPath="Name" />
</StackPanel>

视图模型:

public class Physician
{
    private int _selectedClinicId;

    public Physician()
    {
        Name = "Overpaid consultant";
        Clinics = new ObservableCollection<Clinic>
                      {
                          new Clinic {Id = 0, Name = "Out Patients"},
                          new Clinic {Id = 1, Name = "ENT"},
                          new Clinic {Id = 2, Name = "GE"},
                      };
    }

    public string Name { get; set; }
    public IEnumerable<Clinic> Clinics { get; private set; }

    public int SelectedClinicId
    {
        get { return _selectedClinicId; }
        set
        {
            if (value != _selectedClinicId)
            {
                Debug.WriteLine(string.Format("setting clinic to: {0}",value));
                _selectedClinicId = value;
            }
        }
    }
}

public class Clinic
{
    public int Id { get; set; }
    public string Name { get; set; }
}
请注意,对于可读/可写的属性,您可能希望引发属性更改通知。

2
Phil,感谢您抽出时间回复,但是我对您的答案有些迷惑,抱歉。我拥有一个完整的诊所列表,ListBox是由它填充的,我想要突出显示的是医生对象诊所列表中存在的诊所。此外,如果我选择了原始列表中没有的诊所,我希望将其添加,或者如果我取消选择,则将其从医生的诊所列表中删除。这可能是那种简单绑定无法完成的事情之一。 - Mike Malter

3
您的问题是 SelectedValue。在 ListBox 层面上,绑定多个选择对象是不支持的。使用绑定的唯一真正方法是通过重新设计您的 ViewModel,使得从绑定返回的诊所列表代表 所有 诊所,并且每个对象都应该有一个 IsSelected(或类似)属性。
然后,您可以使用样式来处理多选,通过在您的 ListBox 节点中添加以下 XAML 代码:
<ListBox.ItemContainerStyle>
   <Style TargetType="{x:Type ListBoxItem}">
      <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
   </Style>
</ListBox.ItemContainerStyle>

1

您需要使用带有TextBox的模板来输入名称,使用ListBox来选择诊所,并将内部ListBox路径绑定到诊所。 DisplayMemberPath是一个快捷方式,用于单个TextBox。如果您需要更多,则需要使用单独的控件。


你能详细说明一下吗?我很感谢你的回答,但我不确定它与在Listbox中选择项目有什么关系。我错过了什么吗?谢谢。 - Mike Malter
1
BalamBalam的意思是列表框可以显示诊所的更多属性(名称、地址、死亡率等)。WPF中的列表框非常灵活,可以使用模板显示几乎任何内容。 - Phil
我很感激你的额外想法,但我不需要那些。我正在询问如何将集合绑定到Listbox,以便这些项目被选中,反之亦然。 - Mike Malter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接