这是我在这里的第一篇文章。
我遇到的问题与DataGrid(WPF)中的复选框有关。 抱歉,由于我是新用户,我无法附上截图以更好地理解问题。
问题:即使其中一个子项未选中,也会检查DataHeader列复选框。 我希望解决方案可以解决这个问题,这样当用户明确地取消选中其中一个子节点时,应该隐式取消选中ALL(Header)。
请帮帮我们......谢谢!
Plz检查链接。我希望解决方案能够像这样工作。 http://www.codeproject.com/Articles/42437/Toggling-the-States-of-all-CheckBoxes-Inside-a-Dat#
答案 0 :(得分:1)
我已经说你有一个绑定到viewmodel的视图。在我的代码中,这个viewmodel有一个Elements集合,它们绑定到gridview ItemsSource和属性HeaderChecked,它代表列标题的状态。每个元素都有一个属性IsChecked。当然,ViewModel支持INotifyPropertyChanged。
这是 ViewModel 的代码(DataEventsSource只实现了INotifyPropertyChanged):
public class MainViewModel : DataEventsSource
{
private ObservableCollection<Element> _elements = new ObservableCollection<Element>
{
new Element {IsChecked = false},
new Element {IsChecked = false},
new Element {IsChecked = false},
new Element {IsChecked = false}
};
public MainViewModel()
{
foreach (var element in _elements)
{
element.PropertyChanged += OnElementPropertyChanged;
}
}
private void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "IsChecked")
{
bool? headerChecked = null;
if (Elements.All(el => el.IsChecked))
{
headerChecked = true;
}
if (Elements.All(el => !el.IsChecked))
{
headerChecked = false;
}
HeaderChecked = headerChecked;
}
}
public ObservableCollection<Element> Elements
{
get
{
return _elements;
}
set
{
_elements = value;
}
}
private bool? _headerChecked = false;
public bool? HeaderChecked
{
get
{
return _headerChecked;
}
set
{
_headerChecked = value;
OnPropertyChanged("HeaderChecked");
}
}
}
public class Element : DataEventsSource
{
private bool _isChecked;
public bool IsChecked
{
get
{
return _isChecked;
}
set
{
_isChecked = value;
OnPropertyChanged("IsChecked");
}
}
}
当收集元素发生更改时,如您所见,HeaderChecked属性在OnElementPropertyChanged方法中更新。
这就是观点:
<强>代码隐藏强>:
public partial class MainWindow
{
private readonly MainViewModel _viewModel = new MainViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = _viewModel;
}
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
foreach (var element in _viewModel.Elements)
{
element.IsChecked = true;
}
}
private void CheckBox_UnChecked(object sender, RoutedEventArgs e)
{
foreach (var element in _viewModel.Elements)
{
element.IsChecked = false;
}
}
}
接下来是 XAML 的主网格(为简单起见,它只包含一列):
<Grid x:Name="LayoutRoot">
<DataGrid x:Name="dataGrid" CanUserAddRows="False" AutoGenerateColumns="False" ItemsSource="{Binding Elements}">
<DataGrid.Columns>
<DataGridCheckBoxColumn x:Name="checkboxColumn" Binding="{Binding IsChecked, Mode=TwoWay}" IsThreeState="True" Width="50" >
<DataGridCheckBoxColumn.HeaderTemplate>
<DataTemplate x:Name="dtAllChkBx">
<CheckBox Name="cbxAll" Content="Label" IsChecked="{Binding Path=DataContext.HeaderChecked, ElementName=LayoutRoot, Mode=TwoWay}" Checked="CheckBox_Checked" Unchecked="CheckBox_UnChecked"></CheckBox>
</DataTemplate>
</DataGridCheckBoxColumn.HeaderTemplate>
</DataGridCheckBoxColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
我希望这段代码会对你有所帮助,如果我误解了你,请告诉我。
答案 1 :(得分:1)
//this event is for **Checked and UnChecked** of up check box (cbxall)
private void UpCheckbox_Checked(object sender, RoutedEventArgs e)
{
//checkBox1 = cbxall (your up checkbox)
if (checkBox1.IsChecked == true)
{
dataGrid1.Items.OfType<YourClass>().ToList().ForEach(x => x.IsChecked = true);
}
else
{
dataGrid1.Items.OfType<YourClass>().ToList().ForEach(x => x.IsChecked = false);
}
}
//this event is for all other check box
//**Checked and UnChecked** of all other check box is this event
private void OtherCheckbox_Checked(object sender, RoutedEventArgs e)
{
//checkBox1 = cbxall (your up checkbox)
if (dataGrid1.Items.OfType<YourClass>().All(x => x.IsChecked == true))
{
checkBox1.IsChecked = true;
}
else if (dataGrid1.Items.OfType<YourClass>().All(x => x.IsChecked == false))
{
checkBox1.IsChecked = false;
}
else
{
checkBox1.IsChecked = null;
}
}
...