Файл JavaScript может получить свое собственное имя?

Мы используем глобальный файл по имени GlobalAssemblyInfo.cs и локальный по имени AssemblyInfo.cs. Глобальный файл содержит следующие атрибуты:

 [assembly: AssemblyProduct("Your Product Name")]

 [assembly: AssemblyCompany("Your Company")]
 [assembly: AssemblyCopyright("Copyright © 2008 ...")]
 [assembly: AssemblyTrademark("Your Trademark - if applicable")]

 #if DEBUG
 [assembly: AssemblyConfiguration("Debug")]
 #else
 [assembly: AssemblyConfiguration("Release")]
 #endif

 [assembly: AssemblyVersion("This is set by build process")]
 [assembly: AssemblyFileVersion("This is set by build process")]

локальный AssemblyInfo.cs содержит следующие атрибуты:

 [assembly: AssemblyTitle("Your assembly title")]
 [assembly: AssemblyDescription("Your assembly description")]
 [assembly: AssemblyCulture("The culture - if not neutral")]

 [assembly: ComVisible(true/false)]

 // unique id per assembly
 [assembly: Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")]

можно добавить GlobalAssemblyInfo.cs использование следующей процедуры:

  • Выбор Добавляют/Существующими Объект... в контекстном меню проекта
  • GlobalAssemblyInfo.cs
  • Выбора Разворачивают Добавлять-кнопку путем нажатия, что мало стрелки вниз справа
  • Выбор, "Добавляют Как Ссылка" в выпадающем списке
кнопок
9
задан Factor Mystic 10 July 2012 в 21:52
поделиться

3 ответа

У Беа Столльниц было хорошее сообщение в блоге об использовании для этого расширения разметки под заголовок «Как я могу установить несколько стилей в WPF?»

Этот блог сейчас мертв, поэтому я воспроизводю сообщение здесь


WPF и Silverlight оба предлагают возможность наследовать стиль из другого стиля с помощью «BasedOn " свойство. Эта функция позволяет разработчикам организовывать свои стили, используя иерархию, аналогичную наследованию классов. Рассмотрим следующие стили:

<Style TargetType="Button" x:Key="BaseButtonStyle">
    <Setter Property="Margin" Value="10" />
</Style>
<Style TargetType="Button" x:Key="RedButtonStyle" BasedOn="{StaticResource BaseButtonStyle}">
    <Setter Property="Foreground" Value="Red" />
</Style>

С этим синтаксисом для Button, использующего RedButtonStyle, свойство Foreground будет установлено на Red, а свойство Margin - на 10.

Эта функция существует в WPF в течение долгого времени, и это новинка Silverlight 3.

Что, если вы хотите установить более одного стиля для элемента? Ни WPF, ни Silverlight не предлагают готового решения этой проблемы. К счастью, есть способы реализовать это поведение в WPF, о которых я расскажу в этом сообщении блога.

WPF и Silverlight используют расширения разметки для предоставления свойствам значений, для получения которых требуется некоторая логика. Расширения разметки легко узнать по фигурным скобкам, окружающим их в XAML. Например, расширение разметки {Binding} содержит логику для извлечения значения из источника данных и его обновления при возникновении изменений; расширение разметки {StaticResource} содержит логику для получения значения из словаря ресурсов на основе ключа. К счастью для нас, WPF позволяет пользователям писать свои собственные расширения разметки. Эта функция пока отсутствует в Silverlight, поэтому решение в этом блоге применимо только к WPF.

Другие написали отличные решения для объединения двух стилей с использованием расширений разметки. Однако мне нужно было решение, которое обеспечивало бы возможность объединять неограниченное количество стилей, что немного сложнее.

Написать расширение разметки несложно. Первый шаг - создать класс, производный от MarkupExtension, и использовать атрибут MarkupExtensionReturnType, чтобы указать, что вы хотите, чтобы значение, возвращаемое вашим расширением разметки, было типа Style.

[MarkupExtensionReturnType(typeof(Style))]
public class MultiStyleExtension : MarkupExtension
{
}

Указание входных параметров для расширения разметки

Мы ' Я бы хотел дать пользователям нашего расширения разметки простой способ указать стили для объединения. По сути, есть два способа, которыми пользователь может указать входные данные для расширения разметки. Пользователь может устанавливать свойства или передавать параметры конструктору. Поскольку в этом сценарии пользователю нужна возможность указать неограниченное количество стилей, мой первый подход заключался в создании конструктора, который принимает любое количество строк, используя ключевое слово «params»:

public MultiStyleExtension(params string[] inputResourceKeys)
{
}

Моя цель состояла в том, чтобы иметь возможность написать входы следующим образом:

<Button Style="{local:MultiStyle BigButtonStyle, GreenButtonStyle}" … />

Обратите внимание на запятую, разделяющую разные ключи стиля. К сожалению, пользовательские расширения разметки не поддерживают неограниченное количество параметров конструктора, поэтому такой подход приводит к ошибке компиляции. Если бы я знал заранее, сколько стилей я хочу объединить, я мог бы использовать тот же синтаксис XAML с конструктором, принимающим желаемое количество строк:

public MultiStyleExtension(string inputResourceKey1, string inputResourceKey2)
{
}

В качестве временного решения я решил, что параметр конструктора принимает одну строку, которая задает имена стилей, разделенные пробелами. Синтаксис неплох:

private string[] resourceKeys;

public MultiStyleExtension(string inputResourceKeys)
{
    if (inputResourceKeys == null)
    {
        throw new ArgumentNullException("inputResourceKeys");
    }

    this.resourceKeys = inputResourceKeys.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

    if (this.resourceKeys.Length == 0)
    {
        throw new ArgumentException("No input resource keys specified.");
    }
}

Вычисление выходных данных расширения разметки

Для расчета выходных данных расширения разметки нам необходимо переопределить метод из MarkupExtension под названием «ProvideValue». Значение, возвращаемое этим методом, будет установлено в целевом объекте расширения разметки.

Я начал с создания метода расширения для Style, который знает, как объединить два стиля. Код для этого метода довольно прост:

public static void Merge(this Style style1, Style style2)
{
    if (style1 == null)
    {
        throw new ArgumentNullException("style1");
    }
    if (style2 == null)
    {
        throw new ArgumentNullException("style2");
    }

    if (style1.TargetType.IsAssignableFrom(style2.TargetType))
    {
        style1.TargetType = style2.TargetType;
    }

    if (style2.BasedOn != null)
    {
        Merge(style1, style2.BasedOn);
    }

    foreach (SetterBase currentSetter in style2.Setters)
    {
        style1.Setters.Add(currentSetter);
    }

    foreach (TriggerBase currentTrigger in style2.Triggers)
    {
        style1.Triggers.Add(currentTrigger);
    }

    // This code is only needed when using DynamicResources.
    foreach (object key in style2.Resources.Keys)
    {
        style1.Resources[key] = style2.Resources[key];
    }
}

С помощью приведенной выше логики первый стиль изменяется, чтобы включить всю информацию из второго. Если есть конфликты (например, оба стиля имеют сеттер для одного и того же свойства), второй стиль выигрывает. Обратите внимание, что помимо копирования стилей и триггеров, я также принял во внимание значения TargetType и BasedOn, а также любые ресурсы, которые может иметь второй стиль. Для TargetType объединенного стиля я использовал тот тип, который является более производным. Если второй стиль имеет стиль «Базедон», я рекурсивно объединяю его иерархию стилей. Если есть ресурсы, я копирую их в первый стиль. Если эти ресурсы упоминаются с помощью {StaticResource}, они статически разрешаются до выполнения этого кода слияния, и поэтому перемещать их не нужно. Я добавил этот код на случай, если мы используем DynamicResources.

Показанный выше метод расширения позволяет использовать следующий синтаксис:

style1.Merge(style2);

Этот синтаксис полезен при условии, что у меня есть экземпляры обоих стилей в ProvideValue. Я не знаю. Все, что я получаю от конструктора, - это список строковых ключей для этих стилей. Если бы в параметрах конструктора была поддержка params, я мог бы использовать следующий синтаксис для получения фактических экземпляров стиля:

<Button Style="{local:MultiStyle {StaticResource BigButtonStyle}, {StaticResource GreenButtonStyle}}" … />
public MultiStyleExtension(params Style[] styles)
{
}

Но это не работает. И даже если ограничения параметров не существовало, мы, вероятно, столкнемся с другим ограничением расширений разметки, когда нам придется использовать синтаксис элемента свойства вместо синтаксиса атрибута для указания статических ресурсов, что является подробным и громоздким (я лучше объясню эту ошибку в предыдущей записи блога ). И даже если бы обоих этих ограничений не существовало, я все равно предпочел бы написать список стилей, используя только их имена - он короче и проще для чтения, чем StaticResource для каждого из них.

Решение состоит в том, чтобы создать StaticResourceExtension, используя код. Имея ключ стиля типа string и поставщика услуг, я могу использовать StaticResourceExtension для получения фактического экземпляра стиля. Вот синтаксис:

Style currentStyle = new StaticResourceExtension(currentResourceKey).ProvideValue(serviceProvider) as Style;

Теперь у нас есть все, что нужно для написания метода ProvideValue:

public override object ProvideValue(IServiceProvider serviceProvider)
{
    Style resultStyle = new Style();

    foreach (string currentResourceKey in resourceKeys)
    {
        Style currentStyle = new StaticResourceExtension(currentResourceKey).ProvideValue(serviceProvider) as Style;

        if (currentStyle == null)
        {
            throw new InvalidOperationException("Could not find style with resource key " + currentResourceKey + ".");
        }

        resultStyle.Merge(currentStyle);
    }
    return resultStyle;
}

Вот полный пример использования расширения разметки MultiStyle: (новая ошибка) .fileName

Или вы можете попробовать следующее:

var filepath;
(function(){ 
    var scripts = document.getElementsByTagName('script'); 
    filepath = scripts[ scripts.length-1 ].src; 
}());

Второй вариант дает вам путь к вашему файлу сценария.

13
ответ дан 4 December 2019 в 08:33
поделиться

Я вижу два способа:

  • поместить в каждый файл JS переменную var filename = 'script.js';
  • получить имя файла, используя