如何使用MVVM模式更新UWP pivot外观

如何使用MVVM模式更新UWP pivot外观,mvvm,uwp,pivot,datatemplate,Mvvm,Uwp,Pivot,Datatemplate,我正在使用MVVM模式开发UWP应用程序。 页面上有一个Pivot控件,下面是一个。看起来是这样的: 我需要突出显示一个pivot元素标题和list元素,然后用户选择一个答案。像这样: 我在更新轴心标题和子列表外观时遇到问题。 我尝试订阅不同的Pivot事件,如LayoutUpdated、Loaded、PivotItemLoaded等,但这种方式并没有解决问题 在创建页面时,似乎所有透视元素都只加载一次。 我已经实现了页眉突出显示,然后页面重新加载或重新激活,但这不是我需要的 如何更新Piv

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

我需要突出显示一个pivot元素标题和list元素,然后用户选择一个答案。像这样:

我在更新轴心标题和子列表外观时遇到问题。 我尝试订阅不同的Pivot事件,如
LayoutUpdated
Loaded
PivotItemLoaded
等,但这种方式并没有解决问题

在创建页面时,似乎所有透视元素都只加载一次。 我已经实现了页眉突出显示,然后页面重新加载或重新激活,但这不是我需要的

如何更新Pivot标题外观和其他元素

在创建页面时,似乎所有透视元素都只加载一次。我已经实现了页眉突出显示,然后页面重新加载或重新激活,但这不是我需要的。 如何更新Pivot标题外观和其他元素

为了满足您的需求,您必须创建逻辑数据模型。

pivotsheader
DataContext
是“问题”。因此,您可以在
Question
类中为
PivotHeader
创建
IsCheck
属性。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" } });
    }
} 
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 ?" });
        }
    }
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();
        }
    }
}
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();
        }
    }
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>

在创建页面时,似乎所有透视元素都只加载一次。我已经实现了页眉突出显示,然后页面重新加载或重新激活,但这不是我需要的。 如何更新Pivot标题外观和其他元素

为了满足您的需求,您必须创建逻辑数据模型。

pivotsheader
DataContext
是“问题”。因此,您可以在
Question
类中为
PivotHeader
创建
IsCheck
属性。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" } });
    }
} 
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 ?" });
        }
    }
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();
        }
    }
}
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();
        }
    }
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>

那么,您希望程序的流程是什么?节目以一个问题开始第一个轴心,然后是什么?是的,节目以一个问题开始第一个轴心。接下来,我选择第一个问题的答案。在回答选择后,我要间歇性地突出显示当前的pivot元素标题,这样用户可以看到他已经回答了问题的内容。我不相信UWP允许您单独更改标题的格式。。您是否考虑过将标题隐藏起来,并将其放入按钮中?然后,您可以绑定单击按钮以将轴导航到特定的轴部分,并自行设置每个按钮的格式。TL;DR:隐藏pivot头并创建您自己的实现。那么您希望程序的流程是什么?节目以一个问题开始第一个轴心,然后是什么?是的,节目以一个问题开始第一个轴心。接下来,我选择第一个问题的答案。在回答选择后,我要间歇性地突出显示当前的pivot元素标题,这样用户可以看到他已经回答了问题的内容。我不相信UWP允许您单独更改标题的格式。。您是否考虑过将标题隐藏起来,并将其放入按钮中?然后,您可以绑定单击按钮以将轴导航到特定的轴部分,并自行设置每个按钮的格式。TL;DR:隐藏pivot头并创建自己的实现。
MainPage中的
WaringConverter
。xaml
是一个简单的类实现
IValueConverter
?您可以添加它来完成回答吗?我已经在
MainPage中发布了
WaringConverter
WaringConverter
。xaml
是一个简单的类实现
IValueConverter
?你能添加它来完成回答吗?我已经发布了
WaringConverter