mvvm - 如何使用MVVM模式更新UWP数据透视表外观

标签 mvvm uwp pivot datatemplate

我正在使用MVVM模式开发UWP应用。
页面上有一个Pivot控件,这里是gist。看起来像这样:

enter image description here

我需要突出显示枢轴元素标题和列表元素,然后用户选择答案。像这样:

enter image description here

我在更新数据透视表头和子列表外观时遇到问题。
我试图订阅不同的Pivot事件,例如LayoutUpdatedLoadedPivotItemLoaded和其他事件,但是这种方式无法解决问题。

创建页面后,似乎所有的数据透视元素都被加载了一次。
我已经实现了标题突出显示,然后重新加载或重新导航了页面,但这不是我所需要的。

如何更新数据透视表头的外观和其他元素?

最佳答案

It seems like all pivot elements are loaded once when page is created. I have achieved that header highlights then page reloaded or renavigated, but this is not what I need. How can I update Pivot header appearence and other elements?



根据您的要求,您必须创建逻辑数据模型。
enter image description here
DataContextPivotHeader是“问题”。因此,您可以在IsCheck类中为PivotHeader设置Question属性。并且listView项的DataContext是“答案”。这样就可以制作“IsRightFlag”
listview项目的属性。这是典型的三明治式建筑。

ViewModel.cs
public class MainPageViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    private ObservableCollection<Question> questions;
    public ObservableCollection<Question> Questions { get => questions; set => questions = value; }

    public MainPageViewModel()
    {
        questions = new ObservableCollection<Question>();
        this.Questions.Add(new Question { Text = "Hello This Nico !", QuestionNumber = "1", RightAnswer = new Answer { Text = "Nico" } });
        this.Questions.Add(new Question { Text = "Hello This Sunteen !", QuestionNumber = "2", RightAnswer = new Answer { Text = "Sunteen" } });
        this.Questions.Add(new Question { Text = "Hello This Lidong !", QuestionNumber = "3", RightAnswer = new Answer { Text = "Lidong" } });
    }
} 

Question.cs
public class Question : INotifyPropertyChanged
    {
        public string QuestionNumber { get; set; }
        public string Text { get; set; }
        public Answer RightAnswer { get; set; }
        public ObservableCollection<Answer> Answers { get => answers; set => answers = value; }
        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private ObservableCollection<Answer> answers;
        private Question CurrentQuestion;
        public event PropertyChangedEventHandler PropertyChanged;
        private Answer selectItem;
        public Answer SelectItem
        {
            get
            {
                return selectItem;
            }
            set
            {
                selectItem = value;

                if (selectItem.Text == CurrentQuestion.RightAnswer.Text)
                {
                    selectItem.IsRightFlag = true;
                    IsCheck = true;
                }
                else
                {
                    selectItem.IsRightFlag = false;
                    IsCheck = false;
                }
                OnPropertyChanged();
            }
        }
        private bool isCheck;
        public bool IsCheck
        {
            get
            {
                return isCheck;
            }
            set
            {
                isCheck = value;
                OnPropertyChanged();
            }
        }
        public ICommand ItemCommand
        {
            get
            {
                return new CommadEventHandler<Question>((item) => ItemClick(item));
            }
        }
        private void ItemClick(Question item)
        {
            this.CurrentQuestion = item;
        }
        public Question()
        {
            answers = new ObservableCollection<Answer>();
            Answers.Add(new Answer { Text = "Lidong" });
            Answers.Add(new Answer { Text = "Nico" });
            Answers.Add(new Answer { Text = "Sunteen" });
            Answers.Add(new Answer { Text = "Who ?" });
        }
    }

Answer.cs
public class Answer : INotifyPropertyChanged
{
    public string Text { get; set; }
    private bool isRigntFlag;
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
    public bool IsRightFlag
    {
        get
        {
            return isRigntFlag;
        }
        set
        {
            isRigntFlag = value;
            OnPropertyChanged();
        }
    }
}

MainPage.xaml
<Page.DataContext>
    <local:MainPageViewModel/>
</Page.DataContext>
<Page.Resources>
    <local:WaringConverter x:Key="converter"/>
    <DataTemplate x:Key="AnswerListDataTemplate">
        <Border Margin="5" BorderThickness="2" BorderBrush="White" Background="Transparent"
                DataContext="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Content}">
            <TextBlock 
                Margin="10" 
                FontSize="28" 
                TextWrapping="WrapWholeWords" 
                Text="{Binding Text}"
                Foreground="{Binding IsRightFlag, Converter={StaticResource converter},Mode=TwoWay}"/>
        </Border>
    </DataTemplate>
    <DataTemplate x:Key="PivotQuestionDataTemplate">
        <StackPanel Orientation="Vertical">
            <TextBlock FontSize="28" Margin="20" TextWrapping="WrapWholeWords" Text="{Binding Text}"/>
            <ListView Grid.Row="2" Margin="0,10" IsItemClickEnabled="True"                  
                          ItemsSource="{Binding Answers}"  
                          SelectedItem="{Binding SelectItem,Mode=TwoWay}"
                          ItemTemplate="{StaticResource AnswerListDataTemplate}"
                      >
                <i:Interaction.Behaviors>
                    <ic:EventTriggerBehavior EventName="ItemClick">
                        <ic:InvokeCommandAction  Command="{Binding ItemCommand}" CommandParameter="{Binding}" />
                    </ic:EventTriggerBehavior>
                </i:Interaction.Behaviors>
            </ListView>
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="PivotHeaderDataTemplate">
        <Border Padding="5" BorderThickness="2" BorderBrush="Gray" Background="{Binding IsCheck ,Converter={StaticResource converter},Mode=TwoWay}">
            <TextBlock FontSize="24" >
                <Run x:Uid="QuestionsPage/QuestionNumber"/>
                <Run Text="{Binding QuestionNumber}"/>
            </TextBlock>
        </Border>
    </DataTemplate>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <Grid Margin="30,50,30,10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Text=""/>
        <Pivot Grid.Row="2"
               x:Name="pivotControl"

               ItemsSource="{Binding Questions}" 
               ItemTemplate="{StaticResource PivotQuestionDataTemplate}"
               HeaderTemplate="{StaticResource PivotHeaderDataTemplate}" 
               >
        </Pivot>
    </Grid>
</Grid>

WaringConverter.cs
public class WaringConverter :IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, string language)
        {
            if((bool)value == true)
            {
                return new SolidColorBrush(Colors.Green);
            }
            else
            {
                return new SolidColorBrush(Colors.Gray);
            }  
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }

enter image description here

关于mvvm - 如何使用MVVM模式更新UWP数据透视表外观,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46928402/

相关文章:

silverlight - WP7 SL - 如何在一个 View 中使用两个不同的 View 模型。一个 VM : Display, 其他用于用户输入并对其进行操作

c# - Caliburn Micro Action

javascript - 我们是否正在倒退使用 JavaScript MVC (MVVM) 框架,如 Backbone.js、Angular 等?

windows-10 - 如何在 UWP 中添加 ListBox 项目上下文菜单

sql - Laravel Eloquent 在每个数据透视表字段条件下获取多对多关系

python - 如何使用每小时值和日期时间索引将宽格式转换为长格式?

mvvm - 获取ListView祖先的DataContext

c# - UWP/ Visual Studio : How to make different builds variants?

xamarin.forms - 如何在 Xamarin.Forms UWP 共享代码项目中使用 Acr.Userdialogs?或任何 XF UWP 项目

mysql - 获取一些行作为列