WPF视图不绑定,除非我之前切换视图

时间:2019-06-19 14:10:21

标签: c# wpf mvvm user-controls datacontext

我正在尝试开发一个WPF应用程序,该应用程序显示3个视图,我们可以使用侧面菜单进行切换。

第一个视图显示文章。我已经在另一个项目中尝试过这种视图,并且效果很好。

我的问题:

问题是,当我在导航中使用它(具有完全相同的代码)时,除非先单击另一个视图然后单击返回,否则图像或标题将不会显示。

这是我当前的代码:

型号:(文章)

    public class Article : INotifyPropertyChanged
    {
        int id;
        string title;
        string link;
        BitmapImage image;

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public Article(int id, string title, string link, BitmapImage image)
        {
            Id = id;
            Title = title;
            Link = link;
            Image = image;
        }

        public int Id
        {
            get => id;
            set { if (value != id) { id = value; NotifyPropertyChanged(); } }
        }

        public string Title
        {
            get => title;
            set { if (value != title) { title = value; NotifyPropertyChanged(); } }
        }

        public string Link
        {
            get => link;
            set { if (value != link) { link = value; NotifyPropertyChanged(); } }
        }

        public BitmapImage Image
        {
            get => image;
            set { if (value != image) { image = value; NotifyPropertyChanged(); } }
        }
    }

ViewModel:(ArticlesViewModel)

public class ArticlesViewModel : INotifyPropertyChanged
    {
        Article[] articles;

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public AccueilViewModel()
        {
            loadArticle();
        }

        public Article[] Articles
        {
            get => articles;
            set { if (value != articles) { articles = value; NotifyPropertyChanged(); } }
        }

         private async void loadArticle()
        {
            var client = new WordPressClient(App.WordpressLink);

            try
            {
                var asychArticles = GetArticles(client);
                await asychArticles;
                var articles = asychArticles.Result;

                int i = 0;
                int a;

                foreach (WordPressPCL.Models.Post p in articles)
                {
                    a = p.FeaturedMedia.Value;

                    var media = GetMedia(client, a);
                    await media;

                    BitmapImage bimage = App.getImage(media.Result.SourceUrl);

                    articleImg[i].Source = bimage;
                    articleTitle[i].Content = p.Title.Rendered.ToUpper();
                    articleLink[i] = p.Link;

                    i++;
                    if (i == 4) break;
                }
            }
            catch (System.Net.Http.HttpRequestException e)
            {

            }
        }
        static async Task<IEnumerable<WordPressPCL.Models.Post>> GetArticles(WordPressClient client)
        {
            var posts = await client.Posts.GetAll();
            return posts;
        }
        static async Task<WordPressPCL.Models.MediaItem> GetMedia(WordPressClient client, int number)
        {
            var media = await client.Media.GetByID(number);
            return media;
        }
    }

视图:(ArticlesView)

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="10*"/>
            <RowDefinition Height="5*"/>
        </Grid.RowDefinitions>

        <Grid Name="Article1" Grid.Row="0" Margin="10,10,10,10" DataContext="{Binding Articles[0]}">
            <Grid.RowDefinitions>
                <RowDefinition Height="5*"/>
                <RowDefinition Height="1*"/>
            </Grid.RowDefinitions>

            <Image Name="Image1" Grid.Row="0" Stretch="UniformToFill" Source="{Binding Image}"/>
            <Button Name="Titre1" Grid.Row="1" Content="{Binding Title}"/>

        </Grid>

        <Grid Grid.Row="1">

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Grid Name="Article2" Grid.Column="0"  Margin="10,10,10,10" DataContext="{Binding Articles[1]}">
                <Grid.RowDefinitions>
                    <RowDefinition Height="5*"/>
                    <RowDefinition Height="1*"/>
                </Grid.RowDefinitions>

                <Image Name="Image2" Grid.Row="0" Stretch="UniformToFill" Source="{Binding Image}"/>
                <Button Name="Titre2" Grid.Row="1" Content="{Binding Title}"/>

            </Grid>

            <Grid Name="Article3" Grid.Column="1"  Margin="10,10,10,10" DataContext="{Binding Articles[2]}">
                <Grid.RowDefinitions>
                    <RowDefinition Height="5*"/>
                    <RowDefinition Height="1*"/>
                </Grid.RowDefinitions>

                <Image Name="Image3" Grid.Row="0" Stretch="UniformToFill" Source="{Binding Image}"/>
                <Button Name="Titre3" Grid.Row="1" Content="{Binding Title}"/>

            </Grid>

            <Grid Name="Article4" Grid.Column="2" Margin="10,10,10,10" DataContext="{Binding Articles[3]}">
                <Grid.RowDefinitions>
                    <RowDefinition Height="5*"/>
                    <RowDefinition Height="1*"/>
                </Grid.RowDefinitions>

                <Image Name="Image4" Grid.Row="0" Stretch="UniformToFill" Source="{Binding Image}"/>
                <Button Name="Titre4" Grid.Row="1" Content="{Binding Title}"/>

            </Grid>

        </Grid>
    </Grid>

MainWindow.xaml:

<Window.Resources>

        <DataTemplate x:Name="ArticlesViewTemplate" DataType="{x:Type viewmodels:ArticlesViewModel}">
            <views:ArticlesView DataContext="{Binding}"/>
        </DataTemplate>
        <DataTemplate x:Name="Feature2ViewTemplate" DataType="{x:Type viewmodels:Feature2ViewModel}">
            <views:Feature2View DataContext="{Binding}"/>
        </DataTemplate>
        <DataTemplate x:Name="Feature3ViewTemplate" DataType="{x:Type viewmodels:Feature3ViewModel}">
            <views:Feature3View DataContext="{Binding}"/>
        </DataTemplate>

</Window.Resources>
<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="4*" />
        </Grid.ColumnDefinitions>

        <Grid Grid.Column="0">
            <StackPanel Grid.Row="1" VerticalAlignment="Top" Margin="20,20,20,0">
                <Button Content="Articles" Click="F1Button_Click"/>
                <Button Content="F2" Click="F2Button_Click"/>
                <Button Content="F3" Click="F3Button_Click"/>
            </StackPanel>
        </Grid>

        <ContentControl Grid.Column="1" Content="{Binding}"/>
    </Grid>

MainWindow.xaml.cs:

public partial class MainWindow : Window
    {
        ArticlesViewModel avm;
        Feature2ViewModel f2vm;
        Feature3ViewModel f3vm;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void F1Button_Click(object sender, RoutedEventArgs e)
        {
            if (avm == null) avm = new AccueilViewModel();
            DataContext = avm;
        }

        private void F2Button_Click(object sender, RoutedEventArgs e)
        {
            if (f2vm == null) f2vm = new CatalogueViewModel();
            DataContext = f2vm;
        }

        private void F3Button_Click(object sender, RoutedEventArgs e)
        {
            if (f3vm == null) f3vm = new MesFormationsViewModel();
            DataContext = f3vm;
        }
    }

总结:

  • 单击 文章 ->不显示任何内容
  • 单击 F2 ,然后 文章 ->不显示任何内容
  • 点击 文章 ,然后依次点击 F2 文章 ->正确显示图像和标题!

关于问题可能来自何方的任何想法? 谢谢。

1 个答案:

答案 0 :(得分:0)

所以问题似乎出在我使用数组的事实上。最初,DataContext为空,因此即使将图像和标题加载到模型视图中,它们也不会显示在视图中。

通过使用ObservableCollection而不是数组解决了此问题。如果我理解正确,当数组最初为null时,NotifyPropertyChanged()显然会通知视图。(?)