【问题标题】:MVVM Binding popover isOpen in datagridMVVM Binding popover isOpen in datagrid
【发布时间】: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>

【问题讨论】:

    标签: c# wpf mvvm popup


    【解决方案1】:
    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。您的视图模型仅通知您的 ObservableCollection 项目的更改,就添加和删除的项目而言。如果您想通知内部属性的更改,您必须这样做

    【讨论】:

      【解决方案2】:

      条件应该实现 INotifyPropertyChanged..

      【讨论】:

      • 对不起,我不明白,视图模型正在实现 INotifyPropertyChanged。 Condition 是绑定到 xaml 的 ObservableCollection 使用的一个简单类。所以 observable 集合发生了变化,并且有了 PropertyChangedEventHandler。
      猜你喜欢
      • 1970-01-01
      • 2017-05-23
      • 1970-01-01
      • 2015-01-26
      • 2023-04-04
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多