【发布时间】:2020-07-30 17:35:32
【问题描述】:
我有两个这样的列表:
<ListView Name="listView" Height="300" ItemsSource="{Binding Resultados}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox
IsChecked="{Binding Path=CommandParameter, RelativeSource={RelativeSource Self}, Converter={StaticResource CheckBoxCeldaConverter}, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
Command="{Binding Path=DataContext.SeleccionarCeldaCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
CommandParameter="{Binding}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="EDIFICIO" DisplayMemberBinding="{Binding NIVEL.PASILLO.EDIFICIO.NOMBRE}"/>
<GridViewColumn Header="PASILLO" DisplayMemberBinding="{Binding NIVEL.PASILLO.NOMBRE}"/>
<GridViewColumn Header="NIVEL" DisplayMemberBinding="{Binding NIVEL.NOMBRE}"/>
<GridViewColumn Header="CELDA" DisplayMemberBinding="{Binding CELDA.NOMBRE}"/>
<GridViewColumn Header="CLASIFICACIÓN" DisplayMemberBinding="{Binding CELDA_CATEGORIA.NOMBRE}"/>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button
Command="{Binding Path=DataContext.MostrarDiasVisitasCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
CommandParameter="{Binding CELDA.CELDA_DIAS_VISITA}"
IsEnabled="{Binding TieneDiasVisita}">
<materialDesign:PackIcon Kind="Eye"/>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<ListView Name="listView2" Height="300" ItemsSource="{Binding CeldasSeleccionadas}" Grid.Column="1" Margin="20 0 0 0">
<ListView.View>
<GridView>
<GridViewColumn Header="EDIFICIO" DisplayMemberBinding="{Binding NIVEL.PASILLO.EDIFICIO.NOMBRE}"/>
<GridViewColumn Header="PASILLO" DisplayMemberBinding="{Binding NIVEL.PASILLO.NOMBRE}"/>
<GridViewColumn Header="NIVEL" DisplayMemberBinding="{Binding NIVEL.NOMBRE}"/>
<GridViewColumn Header="CELDA" DisplayMemberBinding="{Binding CELDA.NOMBRE}"/>
<GridViewColumn Header="CLASIFICACIÓN" DisplayMemberBinding="{Binding CELDA_CATEGORIA.NOMBRE}"/>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button
Command="{Binding Path=DataContext.BorrarCeldaCommand, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
CommandParameter="{Binding}">
<materialDesign:PackIcon Kind="Delete"/>
</Button>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
在第一个列表中,元素有一个 CheckBox,如果按下 CheckBox,则从第二个列表中添加或删除元素,它的 ItemSource 绑定到 ViewModel 中的 CeldasSeleccionadas ObservableCollection。我在第一个列表的 isChecked 属性的绑定中有一个转换器,它检查元素是否存在于 CeldasSeleccionadas ObservableCollection 中,如果存在,则将 isChecked 属性设置为 true。这是因为如果用户更新视图,选定的值会保持选中状态。
现在,在第二个列表中,即绑定到 CeldasSeleccionadas 的列表中,我有一个按钮可以从 CeldasSeleccionadas ObservableCollection 中删除元素。这工作正常,我唯一的问题是,当我从 CeldasSeleccionadas ObservableCollection 中删除元素时,第一个列表中的 CheckBox 将 isChecked 属性保持为真,转换器不会再次被调用,并且不检查元素是否存在于 CeldasSeleccionadas ObservableCollection .
CeldasSeleccionadas 在 ViewModel 中看起来像这样:
public ObservableCollection<CeldaModel> CeldasSeleccionadas { get; set; } = new ObservableCollection<CeldaModel>();
这是向 CeldasSeleccionadas 添加元素的命令:
private ICommand _SeleccionarCeldaCommand;
public ICommand SeleccionarCeldaCommand {
get {
if (_SeleccionarCeldaCommand == null) _SeleccionarCeldaCommand = new RelayCommand(param =>SeleccionarCelda((CeldaModel) param));
return _SeleccionarCeldaCommand;
}
}
void SeleccionarCelda(CeldaModel celda) {
if (CeldasSeleccionadas.Contains(celda)) {
CeldasSeleccionadas.Remove(celda);
}
else {
CeldasSeleccionadas.Add(celda);
}
}
这用于删除元素:
private ICommand _BorrarCeldaCommand;
public ICommand BorrarCeldaCommand {
get {
if (_BorrarCeldaCommand == null) _BorrarCeldaCommand = new RelayCommand(param =>BorrarCelda((CeldaModel) param));
return _BorrarCeldaCommand;
}
}
void BorrarCelda(CeldaModel celda) {
CeldasSeleccionadas.Remove(celda);
}
转换器如下所示:
public class CheckBoxCeldaConverter : Freezable, IValueConverter
{
public CheckBoxCeldaConverter()
{
MyCollection = new ObservableCollection<CeldaModel>();
}
protected override Freezable CreateInstanceCore()
{
return new CheckBoxCeldaConverter();
}
public static readonly DependencyProperty MyCollectionProperty =
DependencyProperty.Register(nameof(MyCollection),
typeof(ObservableCollection<CeldaModel>), typeof(CheckBoxCeldaConverter),
new FrameworkPropertyMetadata(null));
public ObservableCollection<CeldaModel> MyCollection
{
get { return GetValue(MyCollectionProperty) as ObservableCollection<CeldaModel>; }
set { SetValue(MyCollectionProperty, value); }
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (MyCollection.Contains(value as CeldaModel))
{
return true;
}
else
{
return false;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我从 User.Resources 内部的视图中调用它,如下所示:
<UserControl.Resources>
<local:CheckBoxCeldaConverter MyCollection="{Binding CeldasSeleccionadas}" x:Key="CheckBoxCeldaConverter"/>
</UserControl.Resources>
添加或删除 CeldasSeleccionadas ObservableCollection 中的项目时如何触发转换器?
【问题讨论】:
-
CeldaModel 应该知道“我被选中了”。这使得它变得如此简单:将复选框绑定到 CeldaModel 中的“Selected”布尔值,让您使用命令参数作为 CeldaModel 它自己并使用它来制作您想要的东西。
-
此外,您的转换器对我来说似乎太乱了,恕我直言。为什么你必须引用“CeldasSeleccionadas”,如果你让 CeldaModel “更智能”,你就不需要它了。
-
这个方法不错,让我试试吧。
-
更多! “Celdas”的一个实例和两个不同的 ICollectionView(“todas” y “seleccionadas”),并且您将每个列表视图绑定到您想要的每个视图,只有一个源!更符合 MVVM 并遵循 DBMSish 方式来管理信息,如果你不知道 ICollectionView,让我来介绍你这个奇妙的世界:marlongrech.wordpress.com/2008/11/22/icollectionview-explained 但是你必须考虑你是想要两个列表还是两个视图。这是第一步
-
这不是我正在寻找的答案,但我认为这比我正在做的要好得多。还要感谢有关 ICollectionViews 的信息!您能否将您的评论作为答案,以便我选择它作为答案?