我正在尝试在WPF应用程序中创建搜索菜单。所以,我自然而然地在4个不同的ListBox中有一堆不同的搜索条件。我很难配置一个'全选'复选框取消选中ListBox中的所有其他CheckBox。
以下是其中一个ListBox的示例:
<StackPanel x:Name="RegionSelection" Orientation="Vertical" Grid.Row="0" Grid.Column="4">
<TextBlock Style="{DynamicResource LabelTextblockStyle}"
VerticalAlignment="top" HorizontalAlignment="Left"
Margin="4,4,4,4">Regions:</TextBlock>
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<ListBox Margin="4,0" HorizontalAlignment="Left" ItemsSource="{Binding Path=RegionTypes, Mode=TwoWay}" ItemContainerStyle="{DynamicResource NoHighlightList}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<CheckBox Content="{Binding Path=RegionDesc}" Command="{Binding Path=UncheckAllCommand}" Margin="4" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</StackPanel>
这是ViewModel:
private List<SearchRegion> _regionTypes;
public List<SearchRegion> RegionTypes
{
get { return _regionTypes; }
set
{
_regionTypes = value;
RaisePropertyChanged();
}
}
RegionTypes = new List<SearchRegion>
{ new SearchRegion {RegionDesc = "All Regions"},
new SearchRegion {RegionDesc = "Region 4", Region="4"},
new SearchRegion {RegionDesc = "Region 1", Region="1"},
new SearchRegion {RegionDesc = "Region 5", Region="5"},
new SearchRegion {RegionDesc = "Region 2", Region="2"},
new SearchRegion {RegionDesc = "Region 6", Region="6"},
new SearchRegion {RegionDesc = "Region 3", Region="3"}
};
命令:
UncheckAllCommand = new RelayCommand(UncheckAll);
public ICommand UncheckAllCommand {get; private set;}
private void UncheckAll()
{
if(RegionTypes.Any((x) => x.RegionDesc.ToUpper().Equals("ALL REGIONS") && x.IsChecked))
{
RegionTypes.ForEach((x) => x.IsChecked = x.RegionDesc.ToUpper() != "ALL REGIONS" ? false : true);
}
}
不幸的是,它只是没有取消选中ListBox的其余部分。任何帮助将不胜感激。
编辑:我忘了添加包含SearchRegion属性的Class。这是:
public class SearchRegion : BaseModel
{
public SearchRegion() { }
public string RegionDesc { get; set; }
public string Region { get; set; }
bool _isChecked = false;
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
}
}
}
答案 0 :(得分:0)
在您的代码中,我发现了2个问题。
1)您的模型应该实现INotifyPropertyChanged
接口:
public class SearchRegion : INotifyPropertyChanged
{
public SearchRegion() { }
public string RegionDesc { get; set; }
public string Region { get; set; }
bool _isChecked = false;
public bool IsChecked
{
get { return _isChecked; }
set
{
_isChecked = value;
OnPropertyChanged("IsChecked");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string property)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
2)如果命令UncheckAllCommand
在ViewModel中,您的绑定应如下所示:
...
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<CheckBox Content="{Binding Path=RegionDesc}"
Command="{Binding Path=DataContext.UncheckAllCommand, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=ListBox}}"
Margin="4" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
...
如果你写这样的话:
...
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<CheckBox Content="{Binding Path=RegionDesc}"
Command="{Binding Path=UncheckAllCommand}"
Margin="4" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
...
您希望在模型类中声明UncheckAllCommand
(在您的情况下,它是SearchRegion
类)。
答案 1 :(得分:0)
在回答我自己的问题时,我就是这样解决的。请记住,有很多方法可以做我想要的,但这是如何偶然发现它。
在我看来,我不需要命令,因为我创建了一个被操纵的临时列表,然后通知视图。所以这是观点:
<StackPanel x:Name="RegionSelection" Orientation="Vertical" Grid.Row="0" Grid.Column="4">
<TextBlock Style="{DynamicResource LabelTextblockStyle}"
VerticalAlignment="top" HorizontalAlignment="Left"
Margin="4,4,4,4">Regions:</TextBlock>
<StackPanel Orientation="Vertical" HorizontalAlignment="Left">
<ListBox Margin="4,0" HorizontalAlignment="Left" ItemsSource="{Binding Path=RegionTypes, Mode=TwoWay}" ItemContainerStyle="{DynamicResource NoHighlightList}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="2"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<CheckBox Content="{Binding Path=RegionDesc}" Margin="4" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" IsEnabled="{Binding Path=IsEnabled, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</StackPanel>
在ViewModel中,我不得不交换&#39; List&#39; for&#39; ObservableCollection&#39;所以这就是我所拥有的:
private ObservableCollection<SearchRegion> _regionTypes;
public ObservableCollection<SearchRegion> RegionTypes
{
get { return _regionTypes; }
set
{
_regionTypes = value;
RaisePropertyChanged();
}
}
RegionTypes = new ObservableCollection<SearchRegion>
{ new SearchRegion {RegionDesc = "All Regions"},
new SearchRegion {RegionDesc = "Region 4", Region="4"},
new SearchRegion {RegionDesc = "Region 1", Region="1"},
new SearchRegion {RegionDesc = "Region 5", Region="5"},
new SearchRegion {RegionDesc = "Region 2", Region="2"},
new SearchRegion {RegionDesc = "Region 6", Region="6"},
new SearchRegion {RegionDesc = "Region 3", Region="3"}
};
然后我创建了一些逻辑来充当事件,这使得我只有在“所有区域”时才能运行逻辑。选中了复选框。
foreach(var region in RegionTypes.Where((x) => x.RegionDesc.ToUpper().Equals("ALL REGIONS")))
region.PropertyChanged += UncheckAll;
以下是改变不是所有地区&#39;
的复选框状态的逻辑 if (RegionTypes.Any((x) => x.RegionDesc.ToUpper().Equals("ALL REGIONS") && x.IsChecked))
{
foreach (var region in tempRegions.Where((x) => !x.RegionDesc.ToUpper().Equals("ALL REGIONS")))
region.IsChecked = true;
}
RegionTypes = new ObservableCollection<SearchRegion>();
RegionTypes = tempRegions;
这就是它。我创建了templist,从Region类型然后在逻辑完成后将区域类型设置为templist中的值。 如果您有疑问,请告诉我。