问:绑定到ObservableCollection <t>的C#WPF DataGrid未更新

时间:2018-04-05 05:57:33

标签: c# wpf data-binding wpfdatagrid

我目前在我的C#WPF应用程序中遇到了一个问题,这个问题看起来很简单。但即使在阅读了几篇Stackoverflow帖子之后,网上的教程仍然无法解决问题。

我有一个DataGrid,我正在尝试绑定到ObservableCollection。此外,我正在使用MVVM模式(至少我正在尝试)和PRISM。

我的问题是,在向ObservableCollection添加新规则后,不会填充DataGrid。当我正在调试我可以看到的应用程序时,该集合包含了项目。正如你从代码中看到的那样,我使用Bindablebase中的RaisePropertyChanged来激活PropertyChangedEvent。我还将DataGrid的ItemSource绑定到RuleList。

有人能看出我做错了吗?

先谢谢,

迈克尔

这是我的RuleModel.cs:

namespace MyApp.GenericViews.Model
{
    public class RuleModel
    {
        public bool IsEnabled { get; set; }
        public string RuleName { get; set; }
        public string Source { get; set; }
        public string Target { get; set; }
        public string ModuleName { get; set; }
        public string ElementName { get; set; }

        public RuleModel()
        {

        }

    }
}

这是我的View.xaml:

<UserControl
    x:Class="MyApp.GenericViews.View.RulesView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:MyApp.GenericViews.View"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="clr-namespace:MyApp.GenericViews.ViewModel"
    d:DataContext="{d:DesignInstance d:Type=vm:RulesViewModel}"
    d:DesignHeight="600"
    d:DesignWidth="800"
    mc:Ignorable="d">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="40" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Label Content="{Binding Title}" />
        <!--<StackPanel Grid.Row="0" Orientation="Horizontal">
            <Button Content="Add" Style="{StaticResource DefaultDialogButton}" />
            <Button Content="Remove" Style="{StaticResource DefaultDialogButton}" />
        </StackPanel>-->
        <DataGrid
            Name="RulesDataGrid"
            Grid.Row="1"
            Margin="5"
            AutoGenerateColumns="False"
            ItemsSource="{Binding Path=RuleList, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
            <DataGrid.Columns>
                <!--<DataGridCheckBoxColumn Width="40" Binding="{Binding Path=IsEnabled}" />-->
                <DataGridTextColumn
                    Width="100"
                    Binding="{Binding Path=RuleName, UpdateSourceTrigger=PropertyChanged}"
                    Header="Name" />
                <DataGridTextColumn
                    Width="100"
                    Binding="{Binding ModuleName}"
                    Header="Module" />
                <!--<DataGridComboBoxColumn
                    Width="100"
                    Header="Element"
                    ItemsSource="{Binding ModuleList}"
                    SelectedItemBinding="{Binding Path=ElementName}" />-->
                <DataGridTextColumn
                    Width="50*"
                    Binding="{Binding Source}"
                    Header="Source" />
                <DataGridTextColumn
                    Width="50*"
                    Binding="{Binding Target}"
                    Header="Target" />
            </DataGrid.Columns>

        </DataGrid>
    </Grid>
</UserControl>

这是我的ViewModel.cs。

    namespace MyApp.GenericViews.ViewModel
{
    public class RulesViewModel : BindableBase, INavigationAware, IViewModel
    {
        private XmlDatabase _xmlDatabase;
        private readonly IUnityContainer _container;
        private readonly IEventAggregator _eventAggregator;

        public IMyAppView View { get; set; }

        public List<string> ModuleList { get; set; }

        private string _title;
        public string Title
        {
            get { return _title; }
            set
            {
                if (_title != value)
                {
                    _title = value;
                    SetProperty(ref _title, value);
                    RaisePropertyChanged(nameof(Title)); 
                }
            }
        }


        private Rule _selectedRule;
        public Rule SelectedRule
        {
            get { return _selectedRule; }
            set
            {
                if (_selectedRule != value)
                {
                    SetProperty(ref _selectedRule, value);
                    RaisePropertyChanged(nameof(SelectedRule)); 
                }
            }
        }


        private ObservableCollection<RuleModel> _RuleList;

        public ObservableCollection<RuleModel> RuleList
        {
            get { return _RuleList; }
            set
            {
                if (_RuleList != value)
                {
                    SetProperty(ref _RuleList, value, nameof(RuleList));
                    //RaisePropertyChanged(nameof(RuleList));

                    //OnPropertyChanged(nameof(RuleList)); 
                }
            }
        }

        public RulesViewModel(IRuleView view, IUnityContainer c, IEventAggregator evt)
        {
            View = view;
            View.ViewModel = this;

            _container = c;
            _eventAggregator = evt;

            _eventAggregator.GetEvent<RuleCommand>().Subscribe(DoProcessRuleCommand);


        }

        private void DoProcessRuleCommand(RuleCommandType commandType)
        {

            switch (commandType)
            {
                case RuleCommandType.AddRule:
                    if (RuleList.IsNullOrEmpty())
                    {
                        RuleList = new ObservableCollection<RuleModel>();
                    }
                    var newRule = new RuleModel()
                    {
                        RuleName = "new rule",
                    };
                    RuleList.Add(newRule);
                    RaisePropertyChanged(nameof(RuleList));

                    //OnPropertyChanged(nameof(RuleList));
                    break;
                case RuleCommandType.DeleteRule:
                    if (RuleList.IsNeitherNullNorEmpty())
                    {
                        //RuleList.Remove(Selected)
                    }
                    break;
                default:
                    break;
            } 

        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            _xmlDatabase = _container?.Resolve<XmlDatabase>();
            if (_xmlDatabase != null)
            {
                RuleList = new ObservableCollection<RuleModel>(_xmlDatabase.Rules.Select(r => RuleModel.FromSerializable(r)));
            }
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {

        }
    }
}

1 个答案:

答案 0 :(得分:0)

好的,在Ivoros在评论中给我提示回顾UserControl的DataContext之后,我查看了我的View.xaml.cs背后的代码。

我忘了在公共View属性

上忘记返回DataContext

之前:

public IMiCasaViewModel ViewModel { get; set; }

后:

public IMiCasaViewModel ViewModel 
{ 
    get
    {
        return (INormalizationViewModel)DataContext;
    }
    set
    {
        DataContext = value;
    }
}

谢谢!!