带有标题标题

时间:2016-02-12 16:53:17

标签: c# wpf xaml mvvm navigation

我想首先说我是C#,WPF,XAML和MVVM的新手。我还没有能够找到并回答我正在寻找的东西,但我无法判断是否因为它没有被问到或者我是不是我正在寻找错误的地方。如果已经有了一些东西,那么指出我正确的方向将非常感激。

现在我的问题是,我正在尝试使用4个标准制作导航仪表板/面板:

  1. 默认情况下,该按钮仅作为文本
  2. 查看
  3. 悬停时,表示文字是按钮
  4. 选择后,表示该按钮已被选中并保持该状态,直到选择了另一页
  5. 在非常相似的网页组上方放置非按钮标签
  6. Here是我在网上找到的格式示例。

    我使用我发现here的文章开始了MVVM转换。我将MVVM Light Libraries添加到我的项目中并使用了他们的RelayCommand和ViewModelBase。这让我想到了如何将中间标签添加到面板中的项目列表而RadioButtons永远不会取消选择的问题。

    要添加标签,我尝试了基于stackoverflow讨论here的CompositeCollections,但没有成功。然后我尝试复制我已经拥有的过程,然后在它们之间堆叠标签,也没有成功。

    转到取消选择问题,我发现另一个stackoverflow帖子here建议列表,但我的RadioButton样式没有正确应用,我仍然无法弄清楚如何添加标签。

    以下是我对列表代码的看法:

    <ListBox ItemsSource="{Binding PageViewModels}" SelectedItem="{Binding CurrentPageViewModel}">
                <ListBox.ItemContainerStyle>
                    <Style TargetType="{x:Type ListBoxItem}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                    <RadioButton Style="{StaticResource NavRadio}"
                                             Content="{TemplateBinding Content}"
                                             IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsSelected}"/>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ListBox.ItemContainerStyle>
            </ListBox>
    

    这是我在各处使用的RadioButton模板供参考:

    <Style x:Key="NavRadio" TargetType="{x:Type RadioButton}">
        <Setter Property="MinHeight" Value="35"/>
        <Setter Property="MinWidth" Value="200"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RadioButton}">
                    <Grid x:Name="NavButtonGrid">
                        <Rectangle>
                            <Rectangle.Fill>
                                <LinearGradientBrush StartPoint="0,0"
                                                     EndPoint="1,0">
                                    <GradientStop Offset="0"
                                                  Color="{DynamicResource ColorBackNavSelect}"/>
                                    <GradientStop x:Name="SelectStop"
                                                  Offset="0"
                                                  Color="{DynamicResource ColorBackNavSelect}"/>
                                    <GradientStop x:Name="DefaultStop"
                                                  Offset="0"
                                                  Color="Transparent"/>
                                    <GradientStop Offset="1"
                                                  Color="Transparent"/>
                                </LinearGradientBrush>
                            </Rectangle.Fill>
                        </Rectangle>
                        <ContentPresenter x:Name="NavButtonContent"
                                          Margin="30,0,0,0"
                                          VerticalAlignment="Center"
                                          HorizontalAlignment="Left"
                                          TextElement.Foreground="{DynamicResource ForeNav}"
                                          TextElement.FontSize="{DynamicResource NavFontSize}">
                        </ContentPresenter>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="True">
                            <Trigger.EnterActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="DefaultStop"
                                                         Storyboard.TargetProperty="Offset"
                                                         To="1"
                                                         Duration="0:0:0.15"/>
                                        <DoubleAnimation Storyboard.TargetName="SelectStop"
                                                         Storyboard.TargetProperty="Offset"
                                                         To="1"
                                                         Duration="0:0:0.15"
                                                         BeginTime="0:0:0.15"/>
                                    </Storyboard>
                                </BeginStoryboard>
                            </Trigger.EnterActions>
                            <Trigger.ExitActions>
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="SelectStop"
                                                         Storyboard.TargetProperty="Offset"
                                                         To="0"
                                                         Duration="0:0:0.06"/>
                                        <DoubleAnimation Storyboard.TargetName="DefaultStop"
                                                         Storyboard.TargetProperty="Offset"
                                                         To="0"
                                                         Duration="0:0:0.06"
                                                         BeginTime="0:0:0.06"/>
    
                                    </Storyboard>
                                </BeginStoryboard>
                            </Trigger.ExitActions>
                            <Setter TargetName="NavButtonContent" Property="TextElement.Foreground" Value="{DynamicResource ForeNavSelect}"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="NavButtonContent" Property="TextElement.FontWeight" Value="Bold"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="NavButtonContent" Property="TextElement.Foreground" Value="{DynamicResource ForeNavSelect}"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    有什么方法可以完成这项工作吗?我觉得它不是一个不常见的设计所以必须有一些解决方案。我没有想到一个与我所做的完全不同的方向的解决方案,我只是提供了帮助的信息。

    编辑:

    根据所做的评论,我并不认为标签是阻碍我的唯一问题。这是我的MainWindowViewModel的代码:

    #region Fields
    
        private ICommand _changePageCommand;
    
        private IPageViewModel _currentPageViewModel;
        private List<IPageViewModel> _pageViewModels;
    
        #endregion
    
        public MainWindowViewModel()
        {
            // Add available pages
            PageViewModels.Add(new HomeViewModel());
            PageViewModels.Add(new ReportsViewModel());
            PageViewModels.Add(new PurchasesViewModel());
            PageViewModels.Add(new InventoryViewModel());
            PageViewModels.Add(new PackingsViewModel());
            PageViewModels.Add(new HistoryViewModel());
            PageViewModels.Add(new ContactsViewModel());
            PageViewModels.Add(new DefinitionsViewModel());
            PageViewModels.Add(new AdminViewModel());
    
            // Set starting page
            CurrentPageViewModel = PageViewModels[0];
        }
    
        #region Properties / Commands
    
        public ICommand ChangePageCommand
        {
            get
            {
                if (_changePageCommand == null)
                {
                    _changePageCommand = new RelayCommand<object>(
                        param => ChangeViewModel((IPageViewModel)param),
                        param => param is IPageViewModel);
                }
    
                return _changePageCommand;
            }
        }
    
    
        public List<IPageViewModel> PageViewModels
        {
            get
            {
                if (_pageViewModels == null)
                    _pageViewModels = new List<IPageViewModel>();
    
                return _pageViewModels;
            }
        }
    
        public IPageViewModel CurrentPageViewModel
        {
            get
            {
                return _currentPageViewModel;
            }
            set
            {
                if (_currentPageViewModel != value)
                {
                    _currentPageViewModel = value;
                    RaisePropertyChanged("CurrentPageViewModel");
                }
            }
        }
    
        #endregion
    
        #region Methods
    
        private void ChangeViewModel(IPageViewModel viewModel)
        {
            if (!PageViewModels.Contains(viewModel))
                PageViewModels.Add(viewModel);
    
            CurrentPageViewModel = PageViewModels
                .FirstOrDefault(vm => vm == viewModel);
        }
    
        #endregion
    }
    

    如何在保持功能的同时将PageViewModels列表拆分为单独的列表?嵌套列表是一个解决方案吗?或者我可以给每个页面的ViewModel一个名为&#34; Group&#34;的字符串。类似于它的名称&#34;名称&#34;并将控件仅绑定到PageViewModels列表中具有相同字符串的项目#34; Group&#34;?

0 个答案:

没有答案