我正在尝试使用包含复选框和文本块的网格组成的项目填充ListBox。我最初只有一个复选框,但我需要将文本换行,所以我将其更改为带有复选框和文本块的网格,文本块执行文本换行。
当它只是复选框时,绑定工作,但现在它没有。现在,列表框中显示正确的项目数,但它只是一个未选中的复选框(即使我将其设置为后面的代码中检查,见下文)和一个空白文本块。
XAML:
<ListBox
x:Name="lstCalibration"
Margin="304,95,78,24"
Background="#7FFFFFFF"
Width="211"
HorizontalAlignment="Center"
VerticalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Width="auto">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<CheckBox
Content=""
Tag="{Binding Tag}"
IsChecked="{Binding IsChecked}"
Checked="CheckBoxCal_Checked"
Unchecked="CheckBoxCal_Unchecked"
Grid.Row="0" Grid.Column="0"
/>
<TextBlock
Tag="{Binding Tag}"
Text="{Binding Text}"
TextWrapping="Wrap"
Grid.Row="0"
Grid.Column="1"
/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
代码背后:
foreach (Controller item in calList)
{
//fill listbox with cals and correct checked states
Grid grid = new Grid();
CheckBox cb = new CheckBox();
TextBlock tb = new TextBlock();
tb.Text = item.Description;
cb.Tag = tb.Tag = i;
cb.IsChecked = calChecked[i];
if (cb.IsChecked == true)
noneChecked = false;
i++;
Grid.SetRow(cb, 0);
Grid.SetColumn(cb, 0);
grid.Children.Add(cb);
Grid.SetRow(tb, 0);
Grid.SetColumn(tb, 1);
grid.Children.Add(tb);
lstCalibration.Items.Add(grid);
}
答案 0 :(得分:1)
添加此项,并删除该foreach循环,您可以以编程方式创建已在DataTemplate
中设置的所有内容。这是一个非常好的DataTemplate
,但你的代码没有正确使用它。 摆脱 calChecked
; _items[n].IsChecked
现在将完成这项工作。
您可以随时向ListItem
添加新的_items
,它会显示在列表中,或删除现有的PropertyChanged
,它将从列表中消失。那是“可观察的”部分。感谢IsChecked
事件提升,如果您从后面的代码中设置public class ListItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public String Text { get; set; }
private bool _isChecked = false;
public bool IsChecked {
get { return _isChecked; }
set {
_isChecked = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(IsChecked));
}
}
}
,则UI中的相应复选框将自动更新。
private ObservableCollection<ListItem> _items;
public MyWindow()
{
InitializeComponent()
_items = new ObservableCollection<ListItem>(
calList.Select(
cal => new ListItem {
Text = cal.Description,
IsChecked = cal.WhateverElse
}
));
lstCalibration.Items = _items;
}
在代码后面的构造函数中:
DataTemplate
在两个地方对Tag
进行一次小改动:不要浪费时间约束public void CheckBoxCal_Checked(object sender, EventArgs args)
{
var listItem = ((FrameworkElement)sender).DataContext as ListItem;
// Do whatever. listItem.IsChecked will be up to date thanks
// to the binding.
}
。在事件处理程序(你甚至可能不需要)中,只需这样投射:
<CheckBox
Content=""
IsChecked="{Binding IsChecked}"
Checked="CheckBoxCal_Checked"
Unchecked="CheckBoxCal_Unchecked"
Grid.Row="0" Grid.Column="0"
/>
<TextBlock
Text="{Binding Text}"
TextWrapping="Wrap"
Grid.Row="0"
Grid.Column="1"
/>
XAML:
postgres=# create table t (x int );
CREATE TABLE
postgres=# insert into t values (1);
INSERT 0 1
postgres=# insert into t values (NULL);
INSERT 0 1
postgres=# insert into t values (3);
INSERT 0 1
postgres=# select * from t;
x
---
1
3
(3 rows)
postgres=# select (CASE WHEN x is NULL THEN 0 ELSE x END) from t;
x
---
1
0
3
(3 rows)