Как получить дизайн WYSIWYG в Blend / VS без объединенного ResourceDictionary в каждом файле XAML? - PullRequest
8 голосов
/ 15 июня 2009

Я только что удалил большую проблему с памятью, я использовал для слияния наш словарь ресурсов "Темы" в каждом файле xaml, а не просто в app.cs.xaml.

Однако после удаления слияния во всех файлах, кроме App.cs.xaml, я потерял стили / шаблоны времени разработки.

Обратите внимание: это относится только к стилям, объединенным с нашими Themes.xaml (например, Color.xaml, Brushes.xaml - у нас есть один для каждого типа стиля). Вещи, определенные непосредственно в Themes.xaml (чего у нас нет ..), работают.

Я вижу два решения,

1) Закомментируйте слияние в XAML и просто снимите комментарий, когда я захочу поработать с проектами.

2) Имейте это в ctor по умолчанию каждого элемента управления: (возможно, работает только в Blend)

#if DEBUG
Resources.MergedDictionaries.Add(
                new ResourceDictionary()
                {
                    Source = new System.Uri(@"RD.xml")
                }
                );
#endif

Должен быть лучший способ получить время редактирования страниц и элементов управления, кто-нибудь знает?

Спасибо!

Ответы [ 6 ]

10 голосов
/ 09 августа 2011

Blend 4 поддерживает «ресурсы времени разработки», которые также поддерживает Visual Studio 2010. Смотри http://adamkinney.wordpress.com/2010/05/04/design-time-resources-in-expression-blend-4-rc/.

Это практически просто ResourceDictionary, который содержит любые MergedDictionaries, которые вам нравятся, и отображается в файле проекта следующим образом (автоматически добавляется Blend):

<Page Include="Properties\DesignTimeResources.xaml" Condition="'$(DesignTime)'=='true' OR ('$(SolutionPath)'!='' AND Exists('$(SolutionPath)') AND '$(BuildingInsideVisualStudio)'!='true' AND '$(BuildingInsideExpressionBlend)'!='true')">
  <Generator>MSBuild:Compile</Generator>
  <SubType>Designer</SubType>
  <ContainsDesignTimeResources>true</ContainsDesignTimeResources>
</Page>

Отлично работает.

8 голосов
/ 17 ноября 2009

Что я делаю, это добавляю класс, который наследует от ResourceDictionary и переопределяет свойство источника, чтобы проверить, является ли IsInDesignMode истинным.

Если это так, я устанавливаю источник, в противном случае я оставляю источник пустым (что предотвращает слияние словаря во время выполнения)

public class BlendMergedDictionary : ResourceDictionary
{
    public bool IsInDesignMode
    {
        get
        {
            return (bool)DependencyPropertyDescriptor.FromProperty(
                            DesignerProperties.IsInDesignModeProperty,
                            typeof(DependencyObject)
                            ).Metadata.DefaultValue;
        }
    }

    public new Uri Source
    {
        get { return base.Source; }
        set
        {
            if (!IsInDesignMode)
                return;

            Debug.WriteLine("Setting Source = " + value);
            base.Source = value;
        }
    }
}

Теперь, когда мне нужно сослаться на словарь в Blend, я сливаюсь в словарь вот так

<ResourceDictionary.MergedDictionaries>
            <BlendHelpers:BlendMergedDictionary Source="Foo.xaml" />
</ResourceDictionary.MergedDictionaries>

Вам по-прежнему приходится «сливать» словарь в каждом файле, но вы не платите штраф за фактическую загрузку словаря во время выполнения. Объединение существует только для поддержки поведения во время разработки.

1 голос
/ 04 января 2011

Вопрос Джейнса на самом деле связан с этим, у меня та же проблема. я создал подкласс ResourceDictionary, как предложил Фуванадил, однако во время разработки это выдает исключение «префикс Uri не перекодирован»

Я получаю эту ошибку, даже если все подклассы присваивают свойство base.Source ResourceDictionary. Если я заменю свой собственный ResourceDictionary обычным, он будет работать нормально, так что я предполагаю, что разработчик сидра делает что-то особенное, возможно, заменяя ResourceDictionary чем-то другим

Я не пробовал это в смеси, но я получаю это в VS2010 (sp1 beta) Может кто-нибудь подтвердить, что опубликованный awnser работает в vs2010?

-edit-

Возможно, что дизайнер на основе wpf отключает логику определения местоположения ресурса. Я читал в другом месте , что пакетные URI основаны на сборке -executing, а не на сборке -local-. я сообщу, что я найду

-edit2 / решение-

Хорошо, поэтому мне удалось заставить решение Foovanadil работать в VS2010, вот сделка. Оказывается, я был наполовину прав, предположительно потому, что конструктор wpf в VS2010 сам по себе написан на wpf или, чтобы обеспечить лучший опыт проектирования, ResourceDictionary (или какой-то другой класс, который вместо этого использует VS2010) ведет себя по-разному во время разработки.

Оказывается, VS заменяет URI, введенный в xaml. Аттестация экземпляра VS и установка точки останова в установщике для Source показывает, что фактическое передаваемое значение отличается от того, что мы ожидаем.

Учитывая xaml:

<Window.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <local:DesignTimeResourceDictionary Source="myxamlfile.xaml"  />
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Window.Resources>

Source установлено на

markup://1/file:///c:/PathtoMyapp/MainWindow.xaml#0/myxamlfile.xaml

вместо

/myxamlfile.xaml

Вот почему мы получаем исключение для недействительного Uris.

Точно, когда и где VS2010 редактирует URI s, этот способ во время разработки мне не известен, но переименование свойства Source в DesignTimeResourceDictionary во что-то другое не решает проблему.

К счастью, есть обходной путь. Если мы изменим тип Source с Uri на String, конструктор VS не изменит значение. Затем в установщике мы создаем Uri и передаем его базовому свойству:

public new String Source {
  get {
    return base.Source.ToString();
  }
  set {
    if( !IsInDesignMode )
      return;
    base.Source = new Uri( value, UriKind.RelativeOrAbsolute );
  }
}

Обратите также внимание, что если вы используете этот подход (или любой другой, который я обнаружил, например, использование x: class в файле ресурсов и создание экземпляра его непосредственно из xaml) приведет к тому, что стили не будут обновлены, пока вы не соберете . Использование стандартного ResourceDictionary приведет к обновлению конструктора, как только вы отредактируете импортированные файлы ресурсов (даже перед сохранением). Это также указывает на то, что дизайнер обрабатывает ResrouceDictionary по-разному во время разработки.

Надеюсь, кто-нибудь найдет это полезным :)

0 голосов
/ 22 октября 2009

Вы можете добавить ресурс distionary в Resources of App.xaml, который отлично работает для меня. Или, может быть, я не получаю тебя.

0 голосов
/ 24 июля 2009

Идея сценария не кажется мне хорошей идеей. У вас будет так много «фальшивых» ревизий в вашем контроле исходного кода, и я предполагаю, что вам придется потратить много времени на его настройку.

Я надеялся, что VS2010 и Expression Blend 3 сделают большие улучшения в этой области. Кто-нибудь пробует бета-версии и знает?

0 голосов
/ 15 июня 2009

Другой способ сделать это (путь, которым мы сейчас покажем): попросите сценарий перед сборкой закомментировать слияние во всех файлах XAML.

усложняет отладку проблем с памятью и т. Д. В режиме отладки, но может быть полностью автоматизирован и устраняет проблемы в окончательном выпуске.

...