带有 DataTemplate 的 ListBox 识别 SelectedItem
ListBox with DataTemplate recognize SelectedItem
我有一个 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));
}
}
如果您想知道用户何时 checked/unchecked 复选框,您需要触发复选框中的事件。
使用这样的东西:
private void MyCheckBox_Checked(object sender, RoutedEventArgs e)
{
//check IsChecked of MyCheckBox here
}
我可以看到两种方式:
- 由于您使用的是 MVVM,因此在 MyListItem2 class (Microsoft Reference on INotifyPropertyChanged implementation) 上实现 INotifyPropertyChanged 接口。当 IsMarked 值为 set/changed 时引发 属性 更改事件,然后连接到项目的 PropertyChanged 事件处理程序以确定何时更改。 .或者
如果您有代码隐藏,请在 XAML 的复选框本身上添加 "Checked" and/or "Unchecked" 事件处理程序。如下所示。
CheckBox Grid.Column="0" Content="Mark" IsChecked="{Binding IsMarked}"/>
勾选="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
}
尝试设置绑定模式:
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
我有一个 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));
}
}
如果您想知道用户何时 checked/unchecked 复选框,您需要触发复选框中的事件。
使用这样的东西:
private void MyCheckBox_Checked(object sender, RoutedEventArgs e)
{
//check IsChecked of MyCheckBox here
}
我可以看到两种方式:
- 由于您使用的是 MVVM,因此在 MyListItem2 class (Microsoft Reference on INotifyPropertyChanged implementation) 上实现 INotifyPropertyChanged 接口。当 IsMarked 值为 set/changed 时引发 属性 更改事件,然后连接到项目的 PropertyChanged 事件处理程序以确定何时更改。 .或者
如果您有代码隐藏,请在 XAML 的复选框本身上添加 "Checked" and/or "Unchecked" 事件处理程序。如下所示。
CheckBox Grid.Column="0" Content="Mark" IsChecked="{Binding IsMarked}"/>
勾选="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
}
尝试设置绑定模式:
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"