繁体   English   中英

将列表框绑定到 ObservableCollection

[英]Binding a Listbox to a ObservableCollection

所以我试图绑定以下 ViewModel:

public class ViewModel : INotifyPropertyChanged
{
    private ObservableCollection<ListBoxItem> _PlacesOrCities;
    public ObservableCollection<ListBoxItem> PlacesOrCities
    {
        get { return _PlacesOrCities; }
        set { _PlacesOrCities = value; RaisePropertyChanged("PlacesOrCities"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public ViewModel()
    {
        _PlacesOrCities = new ObservableCollection<ListBoxItem>();
    }
}

到以下xaml:

<ListBox Name="lbPlacesCity" ItemsSource="{Binding Path=(gms:MainWindow.ViewModel).PlacesOrCities, UpdateSourceTrigger=PropertyChanged}">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="models:ListBoxItem">
            <TextBlock Style="{StaticResource  MaterialDesignBody2TextBlock}" Text="{Binding Name}" Visibility="{Binding Visibility}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

在代码隐藏中:

public ViewModel ViewModel { get; set; }

public MainWindow()
{
    InitializeComponent();
    ViewModel = new ViewModel();
    DataContext = ViewModel;
}

在触发按钮单击事件时 - 我尝试使用内存列表设置可观察集合的值:

private void StateProvince_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    _CurrentSelectionPlaces = Canada.Provinces
        .FirstOrDefault(x => x.Abbreviation == _SelectedStateProvince_ShortName)
        .Place.OrderBy(x => x.Name).ToList();
    foreach (var currentSelectionPlace in _CurrentSelectionPlaces)
    {
        ViewModel.PlacesOrCities.Add(currentSelectionPlace);
    }    
}

但似乎没有任何项目被添加到集合中。 我是否错误地绑定了它?

我已经尝试了很多解决方案,但它们似乎都没有改变结果 - 列表中的任何项目都没有正确加载到集合中。

编辑:可能值得注意的是,在ViewModel看到的ListBoxItem是一个自定义模型:

public class ListBoxItem
{
    [J("Name")] public string Name { get; set; }
    [J("PostalCodes")] public string[] PostalCodes { get; set; }
    public Visibility Visibility { get; set; } = Visibility.Visible;
}

您应该尝试适应 MVVM 模式,因此列表的填充应该发生在视图模型级别而不是视图的代码后面。

您提到您使用单击事件,而不是这样做,而是尝试将按钮的命令属性绑定到视图模型中的命令,请参阅此链接,其中包含对几种命令类型以及如何使用它们的说明: https:/ /msdn.microsoft.com/en-us/magazine/dn237302.aspx

另一方面,如果您已经在窗口构造函数中设置了数据上下文,要绑定 ListBox 项源,您只需要绑定属性的名称“PlacesOrCities”:

<ListBox Name="lbPlacesCity" ItemsSource="{Binding Path=PlacesOrCities, UpdateSourceTrigger=PropertyChanged}">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="models:ListBoxItem">
            <TextBlock Style="{StaticResource  MaterialDesignBody2TextBlock}" Text="{Binding Name}" Visibility="{Binding Visibility}" />
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

尝试在没有任何模板的情况下加载列表中的项目也是值得推荐的,您可以使用 ListBox DisplayMemberPath 属性来显示名称,一旦您能够加载项目,就应用样式。

同样在您使用 ObservableCollection 的方式中,您实际上需要替换整个集合而不是添加以触发 RaisePropertyChanged,而是尝试使用普通属性。

public ObservableCollection<ListBoxItem> PlacesOrCities {get;set;} = new ObservableCollection<ListBoxItem>();

修改集合将更新 UI,因此无论何时使用 Add 或 Clear,UI 都应该知道它。

希望能帮助到你。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM