我有一个绑定到可观察集合的数据网格。我想在按钮上显示一个鼠标输入事件,显示从数据库中检索的一些内容。
为了提高效率,我想在鼠标悬停时获取这些数据,因此初始渲染速度更快。
我已将鼠标输入和鼠标离开事件绑定到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");
}
BaseViewModel
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));
}
DataGrid列
<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>
答案 0 :(得分:0)
条件应该实现INotifyPropertyChanged ..
答案 1 :(得分:0)
public class Condition : INotifyPropertyChanged
{
public void SetPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
public int Id { get; set; }
public string Description { get; set; }
private bool popUpOpen;
public bool PopUpOpen
{
get { return popUpOpen; }
set
{
popUpOpen = value;
OnPropertyChanged("PopUpOpen");
}
}
public string PopupContent { get; set; }
…
}
您还需要在班级中实现INotifyPropertyChanged。您的viewmodel仅根据添加和删除的项目通知ObservableCollection项目的更改。如果要通知内部属性的更改,则必须执行此操作