programing

WPF 클래스 라이브러리의 어셈블리 전체/루트 수준 스타일

magicmemo 2023. 4. 11. 21:55
반응형

WPF 클래스 라이브러리의 어셈블리 전체/루트 수준 스타일

C#(2008/)이 있습니다.WPF를 지원하는 NET 3.5) 클래스 라이브러리 어셈블리( 문서에 근거).
여러 개의 창을 만들었으며, 이제 창을 위한 공통 스타일 세트를 만들려고 합니다.단, 클래스 라이브러리이기 때문에 (WPF 앱이 아닌) app.xaml(및 포함된 어플리케이션 & 대응하는 어플리케이션)은 없습니다.[Resources](리소스)는 글로벌 액세스를 위해 이러한 스타일을 저장합니다.

그럼: app.xaml(위 참조) 없는 경우 어셈블리의 모든 xaml 파일에 표시되는 스타일 정의의 최상위 세트를 작성하려면 어떻게 해야 합니까?그리고/또는 동작하는 app.xaml을 클래스 라이브러리에 추가할 수 있습니까?

ResourceDictionary.xaml ResourceDictionary 。★★★★★★★★★★★★★★★★★.그것은 버튼 등의 스타일링을 해결하는 것으로 판명되었습니다.에워싸고 있는 창문은 아닙니다.넣을 수 있다Style="{StaticResource MyWindowStyle}"되어 VS 되지만 실제 해석 합니다(My 수 Studio는 에 포함된 을 볼 수 있을 Visual Studio는 VS Design을 참조할 수 있을 입니다. Visual Studio visual visual visual visual visual visual visual visual but but but ( Visual Studio ) 。단, 을 보다 아직 Resource Dictionary 는ll CRL 。


아이디어는 고맙지만 그래도 안 돼...클래스 라이브러리는 암묵적으로 generic.xaml 사용을 지원하지 않는 것 같습니다.클래스 라이브러리 프로젝트에 generic.xaml을 추가하고 빌드 액션을 "Resource"로 설정했습니다.내용은 다음과 같습니다.

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Window}" x:Key="MyWindow">
        <Setter Property="Background" Value="Black"/>
    </Style>
</ResourceDictionary>

테마를 사용하는 창 xaml은 다음과 같습니다.

<Window x:Class="MyAssembly.ConfigureGenericButtons"
    x:ClassModifier="internal"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Style="{StaticResource MyWindow}"
    Title="ConfigureGenericButtons">
...Buttons, etc...
</Window>

VS Design 창은 My Window 스타일(검은색 배경)을 사용하여 창을 표시하지 않지만 컴파일이 잘 되어 부팅됩니다.단, 이 클래스 라이브러리를 포함하는 앱이 호출하여 이 창을 표시하면 XamlParseException이 나타납니다.

이름이 '{MyWindow}'인 리소스를 찾을 수 없습니다.

또한 창이 기본적으로 스타일을 사용하는지 확인하기 위해 Style 매개 변수를 생략했습니다(그리고 generic.xaml에 x:Key를 포함하거나 포함하지 않음).오류는 없지만 generic.xaml에 정의된 내용도 표시되지 않았습니다.

응용 프로그램이 아니라는 경고와 함께 일반적인 사용자 지정 스타일을 Window에서 사용할 수 있도록 허용하는 방법에 대해 잘못 알고 있습니까? (즉, 각 Window의 xaml에서 스타일을 정의할 필요가 없습니다.

추가해 보다

Style={DynamicResource MyStyle}

이 경우 StaticResource를 사용할 수 없습니다.

이건 그들을 위한 일처럼 들리네요.

  1. /themes/generic.xamlResource Dictionary(리소스 딕셔너리)
  2. cs에 다음 합니다.[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
  3. ?
  4. 이익!

일반에 추가한 리소스는 모든 컨트롤에서 사용됩니다. "ResourceDictionary"에 테마 의 테마 등 수 .themes디렉토리로 이동합니다.

추가 정보에 대한 링크를 엽니다: 사용자 지정 테마 생성적용

app.xaml이 없는 경우에도 어플리케이션 레벨의 리소스에 로드할 수 있지만, 이와 같이 하려면 (xaml이 아닌) 코드를 작성해야 합니다.

void LoadIt()
{
     ResourceDictionary MyResourceDictionary = new ResourceDictionary();
     MyResourceDictionary.Source = new Uri("MyResources.xaml", UriKind.Relative);
     App.Current.Resources.MergedDictionaries.Add(  MyResourceDictionary )
}

예를 들면, 다음의 사이트를 확인해 주세요.http://ascendedguard.com/2007/08/wpf-is-how 중 하나.html

WPF 박사(또는 이전에 WPF 박사라고 알려졌던 사람)는 이 주제에 대한 훌륭한 게시물을 가지고 있다.

다음은 Application 개체를 만들고 리소스를 추가한 게시물에서 발췌한 것입니다.

if (Application.Current == null)
{
    // create the Application object
    new Application();

    // merge in your application resources
    Application.Current.Resources.MergedDictionaries.Add(
        Application.LoadComponent(
            new Uri("MyLibrary;component/Resources/MyResourceDictionary.xaml",
            UriKind.Relative)) as ResourceDictionary);
}

어셈블리는 interop을 통해 호스트되기 때문에 다음과 같이 Shutdown Mode 설정을 추가하고 완료되면 종료해야 했습니다.

new Application() { ShutdownMode = ShutdownMode.OnExplicitShutdown };

그것은 마법처럼 작동했다.

그래서 많은 시간을 보낸 후에야 겨우 이 사실을 알게 되었다.방법은 다음과 같습니다.

  1. 라이브러리에서 WPF라는 이름의 새 합니다.themes.
  2. <고객명>themes,, "" " " " " "generic.xaml.
  3. generic.xaml다음 구문을 사용하여 리소스를 추가합니다.

    <SolidColorBrush x:Key="{ComponentResourceKey {x:Type local:UserControl1}, MyEllipseBrush}" Color="Blue" />
    
  4. 컨트롤에서 다음 구문을 사용하여 이 리소스에 액세스합니다.

    Background="{StaticResource {ComponentResourceKey {x:Type local:UserControl1}, MyEllipseBrush}}"
    

주의사항:

  1. 스텝 1과 2는 보통 새로운 WPF 컨트롤 라이브러리를 작성할 때 Visual Studio에 의해 자동으로 수행됩니다.
  2. 는 이 책의 취지를 잘 이해하지 못한다.ComponentResourceKey의 첫 번째 파라미터이지만 필수입니다.이 리소스를 사용할 컨트롤의 이름을 사용합니다.
  3. Visual Studio의 디자이너가 내 경우 리소스를 찾을 수 없었습니다.캐시 문제일 수도 있어요, 잘 모르겠어요.하지만 런타임에는 깔끔하게 작동합니다.
  4. 이 구문에 대한 자세한 내용은 이 MSDN 기사를 참조하십시오.

이걸로 생활이 좀 더 편해지길 바라.

다음으로 모듈 전체에서 리소스를 공유하기 위한 간단한 솔루션을 제시하겠습니다.NET 클래스 라이브러리중요한 것은 XAML Designer의 디스플레이 기능과 동작을 Visual Studio에서 확실하게 유지하는 것입니다.

먼저 다음에서 파생된 새로운 C# 클래스를 추가합니다.ResourceDictionary다음과 같이 합니다.이 클래스의 인스턴스가 기본값을 대체합니다.ResourceDictionary각각에 대해서System.Windows.Control(또는 기타)ResourceDictionary- bearing component)를 클래스 라이브러리에서 공유 리소스를 확인해야 합니다.

ComponentResources.cs:

using System;
using System.Reflection;
using System.Windows;
using System.Windows.Markup;

namespace MyNamespace
{
    [UsableDuringInitialization(true), Ambient, DefaultMember("Item")]
    public class ComponentResources : ResourceDictionary
    {
        static ResourceDictionary _inst;

        public ComponentResources()
        {
            if (_inst == null)
            {
                var uri = new Uri("/my-class-lib;component/resources.xaml", UriKind.Relative);
                _inst = (ResourceDictionary)Application.LoadComponent(uri);
            }
            base.MergedDictionaries.Add(_inst);    //  <--  !
        }
    };
}

이전 코드 스니펫과 이전 코드 스니펫에서는 반드시 프로젝트의 이름 공간 및 어셈블리 파일 이름('.dll' 확장자 없음)으로 치환하십시오.

신규 추가ResourceDictionary XAML 파일을 클래스 라이브러리 프로젝트에 추가합니다.'응용 프로그램' 어셈블리와 달리 Visual Studio UI에는 이 옵션이 없으므로 수동으로 수행해야 합니다.여기에는 클래스 라이브러리 전체에서 공유할 리소스가 포함됩니다.

$(Project Directory)\리소스xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/netfx/2009/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:MyNamespace">

    <!-- define the resources to be shared across the whole class library here -->

    <!-- example for demonstration -->
    <Style TargetType="Rectangle">
        <Setter Property="Fill" Value="Red" />
    </Style>

<ResourceDictionary>

빌드 액션을 "페이지"로 설정하고 파일 속성 정보가 다음과 같이 표시되는지 확인합니다.

여기에 이미지 설명 입력

마지막으로 공유 리소스를 참조해야 하는 프로젝트의 XAML 파일로 이동하여 기본값을 바꿉니다.ResouceDictionary으로 ( ) 。Resources의 속성)에 XAML이 되어 있습니다.ComponentResources# (「C#」코드에서 알 수 , 「C#」코드로 표시됩니다.C# ( 。ComponentResources는 모두 의 공유 합니다.ResourceDictionary이렇게 하다''자체 프라이빗 리소스가 없는 경우에도 공유 리소스를 볼 수 있는 모든 컨트롤에 대해 이 작업을 수행합니다.물론 이 단계를 건너뛰어 필요에 따라 특정 컨트롤을 공유에서 제외할 수도 있습니다.예를 들어 다음과 같습니다.

<UserControl x:Class="MyNamespace.UserControl1"
             xmlns="http://schemas.microsoft.com/netfx/2009/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:MyNamespace">

    <UserControl.Resources>
        <local:ComponentResources>
            <!-- Keep any existing non-shared resources here from before -->
            <!-- Can be empty if this control has no private resources -->
        </local:ComponentResources>
    </UserControl.Resources>

    <!-- to demonstrate that the Style in the above example is effective... -->
    <Grid>
        <Rectangle Width="10" Height="10" />
    </Grid>

</UserControl>

광고대로라면 XAML Designer를 포함한 뛰어난 기능을 발휘합니다.

여기에 이미지 설명 입력

Window에 로드하면 됩니다.리소스. 사전은 해당 창의 자식만 사용할 수 있습니다.창문과 아이들이 사용할 수 있도록 해야 합니다.

app.xaml 파일에 로드해 보십시오.그러면 윈도 수준의 리소스가 아닌 애플리케이션 수준의 리소스가 됩니다.

언급URL : https://stackoverflow.com/questions/404019/assembly-wide-root-level-styles-in-wpf-class-library

반응형