C# ListViewItem已选择双向绑定不起作用
我已经为我的应用程序创建了一个“DarkMode”主题,但是C# ListViewItem已选择双向绑定不起作用,c#,wpf,xaml,data-binding,C#,Wpf,Xaml,Data Binding,我已经为我的应用程序创建了一个“DarkMode”主题,但是列表视图项的已选择绑定不起作用。当我选择一个或多个项目时,它们会按预期高亮显示(即MultiTrigger应用了正确的高亮显示颜色),因此ListView显然认为IsSelected==True。但是从未调用Setter,因此我的模型中的属性从未更新 如果我删除x:Key=“RemoteComputerItem”样式,它工作正常(即调用Setter并更新我的模型)。删除该样式中的所有触发器没有任何区别(我显然看不到高亮显示的项目,但仍然
列表视图项
的已选择
绑定不起作用。当我选择一个或多个项目时,它们会按预期高亮显示(即MultiTrigger应用了正确的高亮显示颜色),因此ListView显然认为IsSelected==True
。但是从未调用Setter,因此我的模型中的属性从未更新
如果我删除x:Key=“RemoteComputerItem”
样式,它工作正常(即调用Setter并更新我的模型)。删除该样式中的所有触发器没有任何区别(我显然看不到高亮显示的项目,但仍然没有调用Setter)。因此,只剩下以下内容:
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Bd">
<GridViewRowPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
</Border>
</ControlTemplate>
暗模式主题的单独资源字典:
<ListView x:Name="ADComputers" Margin="0" Padding="0" Grid.Row="1" Grid.Column="2"
ItemsSource="{Binding SelectedItem.Computers, ElementName=ADTree, Mode=TwoWay}"
SelectionMode="Multiple" ItemContainerStyle="{DynamicResource RemoteComputerItem}">
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource RemoteComputerItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
<Style.Triggers>
<DataTrigger Binding="{Binding StatusText}" Value="Offline">
<Setter Property="Foreground" Value="Gray" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="" Width="20">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Source="" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn x:Name="Name" Width="120" DisplayMemberBinding="{Binding Name}">
<GridViewColumn.Header>
<GridViewColumnHeader Content="Computer Name" util:SortOrderGlyph.IsSorted="False" util:SortOrderGlyph.SortDirection="True">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="SortCol">
<cal:Parameter Value="Name" />
<cal:Parameter Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type GridViewColumnHeader}}}" />
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</GridViewColumnHeader>
</GridViewColumn.Header>
</GridViewColumn>
<!-- More columns like above, removed to shorten -->
</GridView>
</ListView.View>
</ListView>
<Style x:Key="RemoteComputerItem" TargetType="{x:Type ListViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border x:Name="Bd">
<GridViewRowPresenter HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="Bd">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource ControlMouseOverColor}" />
</Setter.Value>
</Setter>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="False" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource SelectedBackgroundColor}" />
</Setter.Value>
</Setter>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="Selector.IsSelectionActive" Value="True" />
<Condition Property="IsSelected" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource SelectedBackgroundColor}" />
</Setter.Value>
</Setter>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
树视图绑定到ADRoot.Children
:
class ADTreeViewModel : OUModel
{
public OUModel ADRoot { get; set; } = new OUModel(null, false);
}
class OUModel : PropertyChangedBase, ITreeViewItemViewModel
{
// TreeView is bound to this property, which holds a collection of more OUModel objects
public BindableCollection<ITreeViewItemViewModel> Children { get; set; } = new BindableCollection<ITreeViewItemViewModel>();
// The ListView's ItemSource is bound to ADTree.SelectedItem.Computers which is this property
public List<RemoteComputer> Computers
{
get { return computers; }
set { computers = value; NotifyOfPropertyChange(); }
}
// PropertyChangedBase is from Caliburn.Micro
class RemoteComputer : PropertyChangedBase
{
// All other properties in this class are being displayed correctly in the ListView, so the DataContext is correct E.g.:
public string Name { get; set; }
private bool isSelected = false;
// The ListViewItem's IsSelected property is bound to this
public bool IsSelected
{
get { return isSelected; }
set
{
isSelected = value;
NotifyOfPropertyChange(); // Caliburn.Micro gets the property name itself
// I've also tried adding the following
NotifyOfPropertyChange(() => Parent.Children);
NotifyOfPropertyChange(() => Parent);
}
}
}
class-ADTreeViewModel:OUModel
{
public-OUModel-ADRoot{get;set;}=new-OUModel(null,false);
}
类OUModel:PropertyChangedBase,ITreeViewItemViewModel
{
//TreeView绑定到此属性,该属性包含更多OUModel对象的集合
public BindableCollection子项{get;set;}=new BindableCollection();
//ListView的ItemSource绑定到ADTree.SelectedItem.Computers,这是此属性
公共列表计算机
{
获取{返回计算机;}
设置{computers=value;NotifyOfPropertyChange();}
}
//PropertyChangedBase来自Caliburn.Micro
类RemoteComputer:PropertyChangedBase
{
//此类中的所有其他属性都在ListView中正确显示,因此DataContext是正确的,例如:
公共字符串名称{get;set;}
private bool isSelected=假;
//ListViewItem的IsSelected属性绑定到此
公选学校
{
获取{return isSelected;}
设置
{
isSelected=值;
NotifyOfPropertyChange();//Caliburn.Micro获取属性名称本身
//我还尝试添加以下内容
NotifyOfPropertyChange(()=>Parent.Children);
NotifyOfPropertyChange(()=>父级);
}
}
}
以下是所选项目的Live Property Explorer:
是错误的。值可以是True或False且不绑定。如果您使用的是行为:那么请尝试{Binding DataContext.IsSelected}谢谢,我刚刚尝试了
{Binding DataContext.IsSelected}
和{Binding RelativeSource={RelativeSource Self},Path=DataContext.IsSelected}
但两者都没有任何区别。您在输出窗口中看到绑定错误吗?请尝试从该信息开始工作。有时,除非您在元素中设置了相同的属性,否则设置程序不会启动。@Prateek在其第一条注释中说的是错误的。样式设置程序的值当然可以是绑定。
是有效的d表达式,前提是ListViewItem的当前DataContext中存在IsSelected属性。@Pratekshrivastava输出窗口中没有绑定错误。我已使用Live属性查看器选择ListViewItem的DataContext,以查看IsSelected属性是否更新(我在选择项目后刷新Live属性窗口),我不仅仅依赖于setter中的断点。
class ADTreeViewModel : OUModel
{
public OUModel ADRoot { get; set; } = new OUModel(null, false);
}
class OUModel : PropertyChangedBase, ITreeViewItemViewModel
{
// TreeView is bound to this property, which holds a collection of more OUModel objects
public BindableCollection<ITreeViewItemViewModel> Children { get; set; } = new BindableCollection<ITreeViewItemViewModel>();
// The ListView's ItemSource is bound to ADTree.SelectedItem.Computers which is this property
public List<RemoteComputer> Computers
{
get { return computers; }
set { computers = value; NotifyOfPropertyChange(); }
}
// PropertyChangedBase is from Caliburn.Micro
class RemoteComputer : PropertyChangedBase
{
// All other properties in this class are being displayed correctly in the ListView, so the DataContext is correct E.g.:
public string Name { get; set; }
private bool isSelected = false;
// The ListViewItem's IsSelected property is bound to this
public bool IsSelected
{
get { return isSelected; }
set
{
isSelected = value;
NotifyOfPropertyChange(); // Caliburn.Micro gets the property name itself
// I've also tried adding the following
NotifyOfPropertyChange(() => Parent.Children);
NotifyOfPropertyChange(() => Parent);
}
}
}