带有 DataTemplate 的 ListBox 识别 SelectedItem

Posted

技术标签:

【中文标题】带有 DataTemplate 的 ListBox 识别 SelectedItem【英文标题】:ListBox with DataTemplate recognize SelectedItem 【发布时间】:2018-01-07 10:49:06 【问题描述】:

我有一个ListBox 和一个简单的DataTemplate、一个CheckBox 和一个TextBox。 如果用户检查了CheckBox,我想得到这个更改的项目,比如ListBox 的属性SelectedItem

我如何从List2 获取元素,它已经改变了?

MyListItem:

public class MyListItem2 : ReactiveObject


    private string _name;
    public string Name
    
        get  return _name; 
        set
        
            this.RaiseAndSetIfChanged(ref _name, value, "Name");
        
    
    private bool _isMarked;
    public bool IsMarked
    
        get  return _isMarked; 
        set
        
            this.RaiseAndSetIfChanged(ref _isMarked, value, "IsMarked");
        
    

查看:

<Window xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DataTemplate.Views.MainWindow"
        xmlns:viewsmodels="clr-namespace:DataTemplate.ViewModels;assembly=DataTemplate"
        xmlns:dt="clr-namespace:DataTemplate;assembly=DataTemplate"
        Title="DataTemplate" Width="700">
<Window.DataContext>
  <viewsmodels:MainWindowViewModel />
</Window.DataContext>

<Grid ColumnDefinitions="250">
  <ListBox Grid.Column="1" Items="Binding List2">
    <ListBox.ItemTemplate>
      <DataTemplate DataType="dt:MyListItem2">
        <Grid ColumnDefinitions="50*,50*">              
          <CheckBox Grid.Column="0" Content="Mark" IsChecked="Binding IsMarked"/>  
          <TextBox Grid.Column="1" Text="Binding Name"/>  
        </Grid>
      </DataTemplate>
    </ListBox.ItemTemplate>
  </ListBox>
</Grid>

视图模型:

public class MainWindowViewModel : ReactiveObject

    public ObservableCollection<MyListItem2> List2  get; set;     

    public MainWindowViewModel()
    
        List2 = new ObservableCollection<MyListItem2>();
        Random rand = new Random();

        for (int i = 0; i < rand.Next(1, 20); i++)
        
            MyListItem2 mli = new MyListItem2();
            mli.Name = "ListItem" + i;
            mli.IsMarked = false;
            mli.PropertyChanged += ItemChanged; 
            List2.Add(mli);
        
    
    private void ItemChanged(object sender, PropertyChangedEventArgs e)
                
        var item = sender as MyListItem2;
        Console.WriteLine(string.Format("changed: 0 1", item.Name, item.IsMarked));            
    

【问题讨论】:

【参考方案1】:

我可以看到两种方式:

由于您使用的是 MVVM,因此请在 MyListItem2 类 (Microsoft Reference on INotifyPropertyChanged implementation) 上实现 INotifyPropertyChanged 接口。在设置/更改 IsMarked 值时引发属性更改事件,然后连接到项目的 PropertyChanged 事件处理程序以确定何时更改。 .或

如果您有代码隐藏,请在 XAML 中的复选框本身上添加“选中”和/或“未选中”事件处理程序。如下所示。

CheckBox Grid.Column="0" Content="Mark" IsChecked="Binding IsMarked"/> Checked="IsMarked_Checked"

代码隐藏

public void IsMarked_Checked(object sender, RoutedEventArgs e)

    var ck = sender As Checkbox;

    if (ck == null) 
    
         return;
    

    // do whatever you need to here using the datacontext of the Checkbox

【讨论】:

对不起,我更新了这个问题。请注意,它是 .net 核心和 AvaloniaUI。 我接受你的第一点,这很有效。我只需要将 PropertyChanged 事件路由到我的 ViewModel。我更新了问题中的代码。【参考方案2】:

如果您想知道用户何时选中/取消选中复选框,则需要从复选框触发事件。

使用这样的东西:

private void MyCheckBox_Checked(object sender, RoutedEventArgs e)

    //check IsChecked of MyCheckBox here

【讨论】:

对不起,我更新了这个问题。请注意,它是 .net 核心和 AvaloniaUI【参考方案3】:

尝试设置绑定模式:

SelectedItem="Binding SelectedItem, Mode=TwoWay"

【讨论】:

我认为棘手的部分是,当我更改文本或复选框时,SelectedItem 并没有改变。

以上是关于带有 DataTemplate 的 ListBox 识别 SelectedItem的主要内容,如果未能解决你的问题,请参考以下文章

当 DataTemplate 为 Button 时,ListBox 项返回字符串

如何从ListBox.ItemTemplate DataTemplate内部调用Button命令来传递参数而不选择ListBox项?

WPF 查找ListBox等DataTemplate下的子控件

使用动态项绑定到Listbox的DataTemplate中的控件DependencyProperty不起作用

怎么选择DataTemplate中的TextBox

如何使用 DataTemplate 访问列表框中的特定项目?