【发布时间】:2017-11-21 19:17:37
【问题描述】:
我有一个绑定到可观察集合的数据网格。我想让按钮上的鼠标输入事件显示从数据库中检索到的一些内容。
为了提高效率,我想在鼠标悬停时获取这些数据,因此初始渲染速度更快。
我已将鼠标进入和鼠标离开事件绑定到 ViewModel 中的 ICommand。这些控制台正确记录了鼠标进入、鼠标离开的行 ID(为简洁起见,省略了鼠标离开)
如果我手动输入 isOpen="true",所有弹出框都会按预期显示。
我遇到的问题是,如果我在命令委托中改变 Observable 集合,它不会更新内容的数据网格。 Observable 集合在调试器中似乎是正确的。
//Conditions.cs
public class Condition
{
public int Id { get; set; }
public string Description { get; set; }
public bool PopupOpen { get; set; }
public string PopupContent { get; set; }
…
}
视图模型
private ObservableCollection<Condition> _conditionsObservableCollection;
public ObservableCollection<Condition> ConditionsObservableCollection
{
get => _conditionsObservableCollection;
set
{
_conditionsObservableCollection = value;
DynamicOnPropertyChanged();
}
}
private ICommand _showConditionChildrenMouseEnterCommand;
public ICommand ShowConditionChildrenMouseEnterCommand=> _showConditionChildrenMouseEnterCommand ??
(_showConditionChildrenMouseEnterCommand = new RelayCommand<int>(ShowConditionChildren));
private void ShowConditionChildren(int id)
{
Console.WriteLine("enter:"+id); // this is output correctly.
foreach (Condition condition in ConditionsObservableCollection)
{
condition.PopupOpen = condition.Id == id;
}
//ConditionsObservableCollection appears to be changed here.
OnPropertyChanged("ConditionsObservableCollection");
}
基础视图模型
public event PropertyChangedEventHandler PropertyChanged;
public void DynamicOnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
数据网格列
<DataGridTemplateColumn Header="Info">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<Button Style="{StaticResource MaterialDesignFlatButton}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction
CommandParameter="{Binding Path=Id}"
Command="{Binding Path=DataContext.ShowConditionChildrenMouseEnterCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
<i:InvokeCommandAction
CommandParameter="{Binding Path=Id}"
Command="{Binding Path=DataContext.HideConditionChildrenMouseLeaveCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
/>
</i:EventTrigger>
</i:Interaction.Triggers>
<materialDesign:PackIcon Kind="InformationVariant"/>
</Button>
<Popup
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
IsOpen="{Binding PopupOpen}">
<StackPanel Background="AntiqueWhite">
<TextBlock Padding="5">Here is a popup for id: <Run Text="{Binding Id}"/></TextBlock>
</StackPanel>
</Popup>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
【问题讨论】: