【问题标题】:View doesn't update another view in wpf mvvm application视图不会更新 wpf mvvm 应用程序中的另一个视图
【发布时间】:2016-07-07 18:00:15
【问题描述】:

我正在开发一个 wpf 应用程序。我有一个外壳,它有一个区域。我有两个视图,一个用于编辑人员对象,另一个用于列出所有人员(可观察的集合)。两个视图工作正常。

每当我使用人员列表视图和更新实体并切换到人员视图时,我都会看到更新的实体。在人员视图中更改实体并再次返回人员视图后,它不会更新视图。 (我正在使用棱镜和统一。)我卡住了。

提前致谢。

//我的人物类

public class Personel : ModelBase, IPerson
{
    [Key]
    public int PersonelId { get; set; }

    public string Ad { get; set; }

    public int CinsiyetId { get; set; }

    public DateTime DogumTarihi { get; set; }

    public string DogumYeri { get; set; }

    public string Foto { get; set; }

    public string IkinciAd { get; set; }

    public int SaglikDurumId { get; set; }

    public string SaglikSorun { get; set; }

    public string Soyad { get; set; }

    public int TahsilId { get; set; }

    public long TCKN { get; set; }

    public string BabaAdi { get; set; }

    public string AnneAdi { get; set; }

    public int NüfusIlId { get; set; }//+

    public string NüfusIlce { get; set; }

    public string Mahalle { get; set; }

    public int CiltNo { get; set; }

    public int AileSiraNo { get; set; }

    public int SiraNo { get; set; }

    public bool MedeniHal { get; set; }

    public DateTime EvlilikTarih { get; set; }

    public int TelefonAsil { get; set; }

    public int TelefonYedek { get; set; }

    public int TelefonEv { get; set; }

    //public string Adres { get; set; }

    //public int IsActive { get; set; }

    //public string Sicil { get; set; }

    public int Boy { get; set; }

    public int Kilo { get; set; }

    public int KanGrubuId { get; set; }//+

    public bool Sigara { get; set; }

    public int YabanciDilId { get; set; }//+

    public int YabanciDilDurumId { get; set; }//+

}

MainWindow.xaml

<Window x:Class="Nehir.YBS.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="700" Width="1280" ShowInTaskbar="False" WindowStartupLocation="CenterScreen" WindowState="Maximized">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.15*"/>
            <ColumnDefinition Width="0.85*"/>
        </Grid.ColumnDefinitions>
        <TreeView Grid.Column="0" Grid.RowSpan="2">
            <TreeViewItem Header="Lists">
                <Hyperlink Command="{Binding NavigateCommand}" CommandParameter="Personel">Personnel List</Hyperlink>                
            </TreeViewItem>
            <TreeViewItem Header="Editing">
                <Hyperlink  Command="{Binding NavigateCommand}" CommandParameter="PersonelInfo">Personnel</Hyperlink>                
            </TreeViewItem>
        </TreeView>
        <Grid Grid.Row="0" Grid.Column="1" Grid.RowSpan="2">
            <ContentControl prism:RegionManager.RegionName="ContentRegion"  VerticalAlignment="Top" HorizontalAlignment="Stretch" />
        </Grid>
    </Grid>
</Window>

MainWindowViewModel.cs

public class MainWindowViewModel : BindableBase
    {
        private string _title = "Prism Unity Application";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private readonly IRegionManager regionManager;

        public DelegateCommand<string> NavigateCommand { get; set; }

        public MainWindowViewModel(IRegionManager regionManager)
        {
            this.regionManager = regionManager;
            NavigateCommand = new DelegateCommand<string>(Navigate);
        }

        private void Navigate(string uri)
        {
            this.regionManager.RequestNavigate("ContentRegion", uri);
        }
    }

Personel.xaml

<UserControl x:Class="Nehir.YBS.Views.Personel"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Nehir.YBS.Views"
             xmlns:prism="http://prismlibrary.com/"
             prism:ViewModelLocator.AutoWireViewModel="True"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="800">
    <Grid VerticalAlignment="Top">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <DataGrid x:Name="personelDataGrid" Grid.Row="0" ItemsSource="{Binding PersonelList,UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" Margin="0,0,280,0">
            <DataGrid.Columns>
                <DataGridTextColumn Header="PersonelId" Binding="{Binding PersonelId, UpdateSourceTrigger=PropertyChanged}"/>
                <DataGridTextColumn Header="Ad" Binding="{Binding Ad, UpdateSourceTrigger=PropertyChanged}"/>
                <DataGridTextColumn Header="Ad2" Binding="{Binding IkinciAd, UpdateSourceTrigger=PropertyChanged}"/>
                <DataGridTextColumn Header="Soyad" Binding="{Binding Soyad, UpdateSourceTrigger=PropertyChanged}"/>
                <DataGridTemplateColumn Header="Doğum Tarihi">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <DatePicker SelectedDate="{Binding DogumTarihi, UpdateSourceTrigger=PropertyChanged}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
        <Button Content="Kaydet" Grid.Row="1" Command="{Binding UpdateCommand}" Width="75" Height="35" Margin="15,0,15,0" VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
    </Grid>
</UserControl>

PersonelViewModel.cs

public class PersonelViewModel : BindableBase
    {
        Repository<Personel, YBSDbContext> repo = new Repository<Personel, YBSDbContext>(new YBSDbContext());

        private ObservableCollection<Personel> personelList;

        public ObservableCollection<Personel> PersonelList
        {
            get { return personelList; }
            set
            {
                SetProperty(ref personelList, value);
            }
        }

        public PersonelViewModel()
        {
            UpdateCommand = new DelegateCommand(Execute, CanExecute);
            PersonelList = new ObservableCollection<Personel>(repo.GetAll());
        }

        private bool CanExecute()
        {
            if (PersonelList is ObservableCollection<Personel>)
            {
                return true;    
            }
            return false;
        }

        private void Execute()
        {
            repo.Save();
        }

        public DelegateCommand UpdateCommand { get; set; }
    }

PersonelInfo.xaml

<UserControl x:Class="Nehir.YBS.Views.PersonelInfo"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"             
             prism:ViewModelLocator.AutoWireViewModel="True"
             VerticalAlignment="Top">
    <Grid VerticalAlignment="Top">
        <Grid.RowDefinitions>
            <RowDefinition Height="0.95*"/>
            <RowDefinition Height="0.05*"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Orientation="Vertical" VerticalAlignment="Top">
            <Expander x:Name="temel" Header="Personel Kişisel Bilgileri" MinWidth="1000" HorizontalAlignment="Left" VerticalAlignment="Top">
                <Grid Background="#FFE5E5E5"  Width="1000">
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="0,15*"/>
                        <ColumnDefinition Width="0,35*"/>
                        <ColumnDefinition Width="0,15*"/>
                        <ColumnDefinition Width="0,35*"/>
                    </Grid.ColumnDefinitions>
                    <TextBox Text="{Binding PersonelInfo.PersonelId, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.Ad, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.IkinciAd, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.Soyad, UpdateSourceTrigger=PropertyChanged}" Grid.Row="3" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.DogumTarihi, UpdateSourceTrigger=PropertyChanged}" Grid.Row="4" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.DogumYeri, UpdateSourceTrigger=PropertyChanged}" Grid.Row="5" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.TCKN, UpdateSourceTrigger=PropertyChanged}" Grid.Row="6" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.Foto, UpdateSourceTrigger=PropertyChanged}" Grid.Row="7" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.AnneAdi, UpdateSourceTrigger=PropertyChanged}" Grid.Row="8" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.BabaAdi, UpdateSourceTrigger=PropertyChanged}" Grid.Row="9" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.MedeniHal, UpdateSourceTrigger=PropertyChanged}" Grid.Row="10" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.EvlilikTarih, UpdateSourceTrigger=PropertyChanged}" Grid.Row="11" Grid.Column="1"/>
                    <TextBlock Text="PersonelId" Grid.Row="0" Grid.Column="0"/>
                    <TextBlock Text="Ad" Grid.Row="1" Grid.Column="0"/>
                    <TextBlock Text="IkinciAd" Grid.Row="2" Grid.Column="0"/>
                    <TextBlock Text="Soyad" Grid.Row="3" Grid.Column="0"/>
                    <TextBlock Text="DogumTarihi" Grid.Row="4" Grid.Column="0"/>
                    <TextBlock Text="DogumYeri" Grid.Row="5" Grid.Column="0"/>
                    <TextBlock Text="TCKN" Grid.Row="6" Grid.Column="0"/>
                    <TextBlock Text="Foto" Grid.Row="7" Grid.Column="0"/>
                    <TextBlock Text="AnneAdi" Grid.Row="8" Grid.Column="0"/>
                    <TextBlock Text="BabaAdi" Grid.Row="9" Grid.Column="0"/>
                    <TextBlock Text="MedeniHal" Grid.Row="10" Grid.Column="0"/>
                    <TextBlock Text="EvlilikTarihi" Grid.Row="11" Grid.Column="0"/>
                </Grid>
            </Expander>
            <Expander x:Name="egitim_saglik"  Header="Eğitim/Sağlık Bilgileri" HorizontalAlignment="Left" VerticalAlignment="Top">
                <Grid Background="#FFE5E5E5" Width="1000">
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="0,15*"/>
                        <ColumnDefinition Width="0,35*"/>
                        <ColumnDefinition Width="0,15*"/>
                        <ColumnDefinition Width="0,35*"/>
                    </Grid.ColumnDefinitions>
                    <TextBox Text="{Binding PersonelInfo.SaglikDurumId, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.SaglikSorun, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.Boy, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.Kilo, UpdateSourceTrigger=PropertyChanged}" Grid.Row="3" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.KanGrubuId, UpdateSourceTrigger=PropertyChanged}" Grid.Row="4" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.Sigara, UpdateSourceTrigger=PropertyChanged}" Grid.Row="5" Grid.Column="1"/>
                    <TextBlock Text="Sağlık Durumu" Grid.Row="0" Grid.Column="0"/>
                    <TextBlock Text="Sağlık Sorunu" Grid.Row="1" Grid.Column="0"/>
                    <TextBlock Text="Boy" Grid.Row="2" Grid.Column="0"/>
                    <TextBlock Text="Kilo" Grid.Row="3" Grid.Column="0"/>
                    <TextBlock Text="Kan Grubu" Grid.Row="4" Grid.Column="0"/>
                    <TextBlock Text="Sigara" Grid.Row="5" Grid.Column="0"/>
                    <TextBox Text="{Binding PersonelInfo.TahsilId, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="3"/>
                    <TextBox Text="{Binding PersonelInfo.YabanciDilId, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="3"/>
                    <TextBox Text="{Binding PersonelInfo.YabanciDilDurumId, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="3"/>
                    <TextBlock Text="TahsilId" Grid.Row="0" Grid.Column="2"/>
                    <TextBlock Text="YabanciDilId" Grid.Row="1" Grid.Column="2"/>
                    <TextBlock Text="YabanciDilDurumId" Grid.Row="2" Grid.Column="2"/>
                </Grid>
            </Expander>
            <Expander x:Name="nufus_iletisim"  Header="Nüfus ve İletişim Bilgileri" HorizontalAlignment="Left" VerticalAlignment="Top">
                <Grid Background="#FFE5E5E5" Width="1000">
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="0,15*"/>
                        <ColumnDefinition Width="0,35*"/>
                        <ColumnDefinition Width="0,15*"/>
                        <ColumnDefinition Width="0,35*"/>
                    </Grid.ColumnDefinitions>
                    <TextBox Text="{Binding PersonelInfo.NüfusIlId, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.NüfusIlce, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.Mahalle, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.CiltNo, UpdateSourceTrigger=PropertyChanged}" Grid.Row="3" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.AileSiraNo, UpdateSourceTrigger=PropertyChanged}" Grid.Row="4" Grid.Column="1"/>
                    <TextBox Text="{Binding PersonelInfo.SiraNo, UpdateSourceTrigger=PropertyChanged}" Grid.Row="5" Grid.Column="1"/>
                    <TextBlock Text="Nüfus İl" Grid.Row="0" Grid.Column="0"/>
                    <TextBlock Text="Nüfus İlçe" Grid.Row="1" Grid.Column="0"/>
                    <TextBlock Text="Mahalle" Grid.Row="2" Grid.Column="0"/>
                    <TextBlock Text="Cilt No" Grid.Row="3" Grid.Column="0"/>
                    <TextBlock Text="Aile Sıra No" Grid.Row="4" Grid.Column="0"/>
                    <TextBlock Text="Sıra No" Grid.Row="5" Grid.Column="0"/>
                    <TextBox Text="{Binding PersonelInfo.TelefonAsil, UpdateSourceTrigger=PropertyChanged}" Grid.Row="0" Grid.Column="3"/>
                    <TextBox Text="{Binding PersonelInfo.TelefonYedek, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="3"/>
                    <TextBox Text="{Binding PersonelInfo.TelefonEv, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="3"/>
                    <TextBox Text="{Binding PersonelInfo.Adres, UpdateSourceTrigger=PropertyChanged}" Grid.Row="5" Grid.Column="3"/>
                    <TextBlock Text="Telefon" Grid.Row="0" Grid.Column="2"/>
                    <TextBlock Text="Telefon Yedek" Grid.Row="1" Grid.Column="2"/>
                    <TextBlock Text="Telefon Ev" Grid.Row="2" Grid.Column="2"/>
                    <TextBlock Text="Adres" Grid.Row="5" Grid.Column="2"/>
                </Grid>
            </Expander>
        </StackPanel>
        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Button Content="Kaydet" Command="{Binding UpdateCommand}" Width="75" Margin="15,0,15,0"/>
        </StackPanel>
    </Grid>
</UserControl>

PersonelInfoViewModel.cs

public class PersonelInfoViewModel : BindableBase
    {
        Repository<Personel, YBSDbContext> repo = new Repository<Personel, YBSDbContext>(new YBSDbContext());

    private Personel personelInfo;

    public Personel PersonelInfo
    {
        get { return personelInfo; }
        set
        {
            SetProperty(ref personelInfo, value);
        }
    }



public PersonelInfoViewModel()

{
    UpdateCommand = new DelegateCommand(Execute,CanExecute);
    personelInfo = repo.FindBy(p => p.TCKN == 11111111111).Single();//for example
}

private bool CanExecute()
{
    return PersonelInfo is Personel;
}

private void Execute()
{
    repo.Save();   
}

public DelegateCommand UpdateCommand { get; set; }

【问题讨论】:

  • 1.你的 Person 类是什么样的? 2. 显示您想要更新的内容的 xaml 是什么样的? 3. 实际修改 person 对象的代码是什么样的?如果您认为包含所有内容会占用太多空间,请使用 SSCCE
  • 你有示例代码吗,不看代码说不出来
  • 最好的猜测是您正在从 PersonalListView 的对象中为 PersonView 创建一个新对象。因此,通过 PersonalListView 更新工作正常,但从 PersonView 更新不会,因为更改不会保留回对象模型的 PersonalListView 副本。
  • 我会尽快添加我的示例代码。对不起。
  • 我的一个对象是人的可观察集合,另一个是人的单个对象

标签: c# wpf unity-container prism


【解决方案1】:

我目前没有足够的信息来确定,但是当我遇到像你描述的那样的问题时,我会检查以下事项:

  • 确保 OnPropertyChanged 正在为您要更新的属性调用。使用BindableBase.SetProperty 设置属性应该可以为您解决这个问题。
  • 确保您的 Xaml 元素正确绑定到您正在更新的属性。确保Binding.Mode Property 未设置为阻止控件更新的内容。

【讨论】:

  • 我的视图模型继承自 BindableBase。绑定模式是两种方式,更新源触发器设置为propertychanged。
【解决方案2】:

最好的猜测是您正在为 PersonView 创建一个新对象 PersonalListView 中的一个对象。所以通过 PersonalListView 更新 工作正常,但从 PersonView 更新并不是因为更改 不会保留回对象的 PersonalListView 副本 模型。 ——雷切尔

看完瑞秋的评论。我意识到,我在两个不同的视图中等待两个不同的对象,它们引用相同的实体(但完全不同的对象)来相互更新。他们只能更新自己的 UI 和数据库。他们无法通知我方法的变化。因此,我创建了在所有应用程序范围内共享的单个存储库对象,并在每次需要时使用它。

//App.xaml.cs

public partial class App : Application
    {
        public static Repository<Personel, YBSDbContext> repo = new Repository<Personel, YBSDbContext>(new YBSDbContext());

        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            var bootstrapper = new Bootstrapper();
            bootstrapper.Run();
        }
    }

我的观点之一是使用应用范围的存储库对象。

public class PersonelInfoViewModel : BindableBase
{
    Repository<Personel, YBSDbContext> repo = App.repo;

我不确定这是不是一个好方法。但它解决了我的问题,至少现在是这样。我会很高兴听到你的 cmets。

【讨论】:

    【解决方案3】:

    我猜你也会在 Personel 类中定义的所有属性上实现属性更改。现在你只有默认的 getter setter 属性。

    由于您正在执行的编辑是属性级别,因此在您实施属性更改之前,您的视图不会更新更改。

    让我知道它是否有效。

    【讨论】:

    • 使用 INotifyPropertyChanged 接口并没有解决我的问题。因为填充 PersonViewModel 中的数据网格的集合和填充 PersonInfoViewModel 的 Personel 对象是两个单独的对象,它们不会相互通知。我使用自己的答案处理了这种情况。谢谢...
    猜你喜欢
    • 2011-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    相关资源
    最近更新 更多