برنامج الأغذية العالمي، MVVM، والقائمة المقدمة اللون

StackOverflow https://stackoverflow.com/questions/1012479

  •  06-07-2019
  •  | 
  •  

سؤال

وأنا جديدة على كل من برنامج الأغذية العالمي وMVVM. لقد بحثت عن وسيلة جيدة لإنشاء القوائم في parttern MVVM حيوي وأنا لا تجد أي شيء لتروق لي، لذلك أنا تدحرجت حل بلدي. كان يعمل، ولكن لسبب ما لون المقدمة (النص) من القوائم في بعض الأحيان (فقط في بعض الأحيان) غير صحيح.

وأضفت رابط للصورة أدناه.

<الإضراب> http://img220.imageshack.us/img220/1912/ badmenu.jpg (الميت لينك)

وبلدي أدنى يعرض قائمة فرعية بشكل صحيح مع المقدمة البيضاء، ولكن القوائم الأم forground تحولت إلى اللون الأسود ويكاد يكون من المستحيل أن يقرأ. إذا كنت قد الثابت ترميز القوائم ثم سيكون لون forground الوالدين تكون بيضاء. إذا كنت أحرك الماوس فوق الأم نصه ستتحول إلى الأبيض وسوف الفرعية تصبح سوداء.

وعلاوة على ذلك، مرة واحدة وأنا أحرك الماوس بعيدا عن الأم، كل من خصائصه منطقية IsHighlighted, IsSubmenuOpen, etc... تصبح كاذبة، والذي يثير الدهشة بالنسبة لي لأنني أعتقد أنها ينبغي أن يبقى وفيا. وأنا لم تكن النتيجة النهائية قادرة على حل هذه مع مشغل النمط.

وهنا هو بلدي XAML.

<Window.Resources>
  <DataTemplate DataType="{x:Type src:ParentMenu}" >
    <Menu >
      <MenuItem Header="{Binding MenuName}" ItemsSource="{Binding ChildMenuItems}" />
    </Menu>
  </DataTemplate>

  <HierarchicalDataTemplate DataType="{x:Type src:ChildMenu}" 
                          ItemsSource="{Binding ChildMenuItems}" >
    <MenuItem Header="{Binding MenuName}" Command="{Binding Path=Command}" />
  </HierarchicalDataTemplate>

'ستاكوفيرفلوو واخفاء بلدي علامة النهاية لWindow.Resources

<DockPanel>
   <Menu DockPanel.Dock="Top" ItemsSource="{Binding Menus}" />

  <Grid>
       <!-- Add additional content here -->
  </Grid>
</DockPanel>

وكلا ParentMenu وChildMenu ترث من فئة المشتركة التي تحمل في الواقع كل القوائم ويعرض القوائم الفرعية من خلال جمع ChildMenuItems. ChildMenuItems هو قائمة الكائنات ChildMenu. بلدي ViewModels فضح قائمة الكائنات ParentMenu.

وربما يكون هناك أفضل السبل لتحقيق ما أريد هنا. هنا مثال:

<الإضراب> img132.imageshack.us/img132/4160/bettermenu.jpg (الميت لينك)

وأي اقتراحات بشأن ما أفعله خطأ و / أو كيفية إصلاح مشكلة العرض؟

هل كانت مفيدة؟

المحلول

والمشكلة هي أن نظام رصد السفن الخاصة بك تلقائيا الحصول على ملفوفة في MenuItems، بحيث يكون لديك أساسا MenuItems متداخلة كما رأس من MenuItems.

ويمكنك التفاف على هذا عن طريق تحديد نمط (والإشارة إليها عن طريق ItemContainerStyle) أن DataBinds لديك نظام رصد السفن (اسم لرأس، DelegateCommands إلى القيادة، الخ) باستخدام MENUITEM مثل نوع البيانات.

ومثال على الطريقة التي يمكن أن تفعل هذا أدناه. علما بأنني قد أسقط HierarchicalDataTemplate لصالح ItemContainerStyle. أخذت أيضا حرية تحديد DataTemplate لMainViewModel الخاص بك لأنه لم يكن من الواضح جدا كيف تم ربط البيانات.

<Window.Resources>
    <DataTemplate DataType="{x:Type src:MainViewModel}">
        <ItemsControl ItemsSource="{Binding Menus}"></ItemsControl>
    </DataTemplate>
    <DataTemplate DataType="{x:Type src:ParentMenu}" >
        <Menu>
            <MenuItem Header="{Binding Name}" 
        ItemsSource="{Binding ChildMenuItems}" ItemContainerStyle="{DynamicResource ChildMenuItemStyle}" />
        </Menu>
    </DataTemplate>
    <Style x:Key="ChildMenuItemStyle" TargetType="MenuItem">
        <Setter Property="Header" Value="{Binding Name}"></Setter>
        <Setter Property="ItemsSource" Value="{Binding ChildMenuItems}"></Setter>
    </Style>
</Window.Resources>

ولقد قطعت أيضا بعض القيادة ملزمة من البساطة، ولكن يمكنك إضافتها مرة أخرى في الضرورة.

نصائح أخرى

وكما هو مطلوب، هي بلدي ViewModels هنا.

وViewModelBase هو معيار واحد التي أنشأتها الاستوديو. وقد حصلت MainVieModel ما يكفي لفي ذلك لإنشاء القوائم اختبار كنت تستخدم لتجربة.

وأساسا أنا أعمل من أجل خلق الطبقات القائمة الوالد / الطفل يمكنني استخدامها مع سلسلة من التطبيقات التي نبيعها إلى مجموعة واسعة من العملاء. آمل أن تجعل من حيث كل زبون يمكن أن يكون لها جمع تخصيص القوائم على أساس احتياجاتهم والتي مستوى، moudles التي اشتروها تراخيص.

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}   

والطبقة العامة MainViewModel: ViewModelBase

{

    public MainViewModel()  {   MakeMenus();    }

    private void MakeMenus()
    {
        // Makes some dummy menus to test with.
        Menus = new ObservableCollection<MyMenuItem>();
        ParentMenu parent;
        ChildMenu child;

        parent = new ParentMenu("First Level");
        Menus.Add(parent);
        child = new ChildMenu(parent, "second level");
        parent.ChildMenuItems.Add(child);
        ChildMenu child2 = new ChildMenu(child, "third level");
        child2.MenuCommand = new DelegateCommand(CommandTest,
                                                   CommandCanExecute_First);
        child.ChildMenuItems.Add(child2);

        child = new ChildMenu(parent, "second level 2");
        parent.ChildMenuItems.Add(child);
        child2 = new ChildMenu(child, "third level 2");
        child2.MenuCommand = new DelegateCommand(CommandTest, 
                                       CommandCanExecute_Second);
        child.ChildMenuItems.Add(child2);

        parent = new ParentMenu("Another First");
        parent.ChildMenuItems.Add(new ChildMenu(parent, "Another Second"));
        Menus.Add(parent);
        OnPropertyChanged("Menus");
    }

    private bool ExecuteToggle { get; set; }
    private void CommandTest()  {   ExecuteToggle = !ExecuteToggle; } 
    public ObservableCollection<MyMenuItem> Menus  {  get; private set;}
    public bool CommandCanExecute_First()   {   return ExecuteToggle;   }
    public bool CommandCanExecute_Second() { return !ExecuteToggle;     }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top