Проблема с привязкой данных ViewModel - PullRequest
0 голосов
/ 29 сентября 2010

У меня есть ViewModel

class FontsViewModel : ObservableObject
{
    public FontsViewModel()
    {
        InitFonts();
    }

    public ObservableCollection<Typeface> Fonts
    {
        get;
        private set;
    }

    protected void InitFonts()
    {
        Fonts = (ObservableCollection<Typeface>)System.Windows.Media.Fonts.SystemFontFamilies;
    }
}

и я связываю его в XAML

<ribbon:RibbonComboBox.DataContext>
    <vm:FontsViewModel />
</ribbon:RibbonComboBox.DataContext>
<ribbon:RibbonGallery>
    <ribbon:RibbonGalleryCategory ItemsSource="{Binding Fonts}">
        <ribbon:RibbonGalleryCategory.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}" FontFamily="{Binding}" />
            </DataTemplate>
        </ribbon:RibbonGalleryCategory.ItemTemplate>
    </ribbon:RibbonGalleryCategory>
</ribbon:RibbonGallery>

когда я пытаюсь бежать, я получаю

System.Windows.Markup.XamlParseException occurred
  Message='The invocation of the constructor on type 'MarkdownEditMVVM.ViewModels.FontsViewModel' that matches the specified binding constraints threw an exception.' Line number '57' and line position '26'.
  Source=PresentationFramework
  LineNumber=57
  LinePosition=26
  StackTrace:
       at System.Windows.Markup.XamlReader.RewrapException(Exception e, IXamlLineInfo lineInfo, Uri baseUri)
       at System.Windows.Markup.WpfXamlLoader.Load(XamlReader xamlReader, IXamlObjectWriterFactory writerFactory, Boolean skipJournaledProperties, Object rootObject, XamlObjectWriterSettings settings, Uri baseUri)
       at System.Windows.Markup.WpfXamlLoader.LoadBaml(XamlReader xamlReader, Boolean skipJournaledProperties, Object rootObject, XamlAccessLevel accessLevel, Uri baseUri)
       at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
       at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
       at MarkdownEditMVVM.MainWindow.InitializeComponent() in d:\Projects\MarkdownEdit\MarkdownEditMVVM\MainWindow.xaml:line 1
       at MarkdownEditMVVM.MainWindow..ctor() in D:\Projects\MarkdownEdit\MarkdownEditMVVM\MainWindow.xaml.cs:line 25
  InnerException: System.InvalidCastException
       Message=Unable to cast object of type 'System.Collections.ObjectModel.ReadOnlyCollection`1[System.Windows.Media.FontFamily]' to type 'System.Collections.ObjectModel.ObservableCollection`1[System.Windows.Media.Typeface]'.
       Source=MarkdownEditMVVM
       StackTrace:
            at MarkdownEditMVVM.ViewModels.FontsViewModel.InitFonts() in D:\Projects\MarkdownEdit\MarkdownEditMVVM\ViewModels\FontsViewModel.cs:line 26
            at MarkdownEditMVVM.ViewModels.FontsViewModel..ctor() in D:\Projects\MarkdownEdit\MarkdownEditMVVM\ViewModels\FontsViewModel.cs:line 15
       InnerException: 

что я делаю не так? Это похоже на измененную версию того, что я вижу в Учебное пособие Лестера по ленте WPF

Ответы [ 2 ]

4 голосов
/ 29 сентября 2010

Два очка:

  1. Вам действительно не нужна коллекция ObservableCollection (если список шрифтов никогда не изменится). Достаточно предоставить свойство IEnumerable<Typeface>.

  2. Вы действительно не должны ссылаться на объект, специфичный для вида, такой как гарнитура из ViewModel. Было бы лучше представить доступные имена шрифтов в виде строк и внедрить доступные имена через некоторый интерфейс службы. Интерфейс службы (на стороне просмотра) будет вызывать System.Windows.Media.Fonts.SystemFontFamilies и приводить к строковым именам. Это дает вам изоляцию для тестируемости (ваши юнит-тесты могут предоставлять свои собственные имена шрифтов.)

4 голосов
/ 29 сентября 2010

Вы не можете преобразовать SystemFontFamilies в ObservableCollection.Вместо этого создайте экземпляр новой коллекции:

  Fonts = new ObservableCollection<Typeface> (Fonts.SystemFontFamilies);

edit: в приведенном выше коде имеется несоответствие между типом свойства и типом коллекции.
Вместо этого используйте один из следующих параметров:

        var myFonts = new ObservableCollection<FontFamily>(Fonts.SystemFontFamilies);

        var typefaces = new ObservableCollection<Typeface>(Fonts.SystemTypefaces);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...