Ostatnio pod wpisem: "[WPF 3D] Malujemy scenę 3D pędzlem" dostałem w ramach komentarza pytanie związane z obrazkami w WPF i ścieżkami w nich. Nie jest to wielki problem, ale postaram się odpowiedzieć.
Otóż problem wyglądał następująco: czytelnik tworzył pędzel przy pomocy kodu:
ImageBrush brush = new ImageBrush(new BitmapImage(new Uri(BaseUriHelper.GetBaseUri(this), "Images/test.png")));
Niestety tak utworzony pędzel nie zawsze generował obraz, taki jak to było oczekiwane. Jak temu zaradzić. Otóż najlepiej odejść od korzystania z takich ścieżek do obrazków lub przynajmniej ograniczyć ilość miejsc, w których takie ścieżki powstają.
Według mnie najwygodniej dodać obrazek do zasobów, np. w następujący sposób:
Wtedy w aplikacji możemy w zasobach napisać w XAML'u:
<BitmapImage x:Key="MyImageSource" UriSource="./ImageResources/logo_zielone_tlo.jpg" /> <ImageBrush x:Key="MyImageBrush" ImageSource="{StaticResource ResourceKey=MyImageSource}"/>
I ostatecznie stworzyć dla przykładu następujące okno:
Powyższe okno powstało przy pomocy następującego kodu XAML:
<Window x:Class="WpfApplication_resources_tests.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="200" Width="200"> <Window.Resources> <BitmapImage x:Key="MyImageSource" UriSource="./ImageResources/logo_zielone_tlo.jpg" /> <ImageBrush x:Key="MyImageBrush" ImageSource="{StaticResource ResourceKey=MyImageSource}"/> </Window.Resources> <Grid> <Label Background="{StaticResource ResourceKey=MyImageBrush}" Width="50" Height="50" VerticalAlignment="Top" HorizontalAlignment="Left"/> <Viewport3D Name="mainViewport"> <Viewport3D.Camera> <PerspectiveCamera FarPlaneDistance="100" LookDirection="-1,-1,-1" UpDirection="0,1,0" NearPlaneDistance="1" Position="3,3,3" FieldOfView="70" /> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="White" Direction="-1,-1,-1" /> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D> <GeometryModel3D.Geometry> <MeshGeometry3D Positions="-2 -2 0 2 -2 0 -2 2 0 2 2 0" Normals="0 0 1 0 0 1 0 0 1 0 0 1" TextureCoordinates="0 1 1 1 0 0 1 0 " TriangleIndices="0 1 2 1 3 2" /> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <DiffuseMaterial Brush="{StaticResource ResourceKey=MyImageBrush}" /> </GeometryModel3D.Material> </GeometryModel3D> </ModelVisual3D.Content> </ModelVisual3D> </Viewport3D> </Grid> </Window>
Nie, obrazków nie trzyma się w zasobach. Ikony, czasem, jak potrzeba, jeden, dwa obrazki, ale nie więcej. One są za duże - EXE-k puchnie, robi się bałagan, trzeba rekompilować, by zmienić obrazek, a i krótsze nie jest.
OdpowiedzUsuńTą linijkę równie dobrze można zapisać jako:
ImageBrush brush = new ImageBrush(new BitmapImage(new Uri("Images/test.png", UriKind.Relative)));
Można to wpakować w jakąś statyczną klasę helpera, by nie pisać nie wiadomo ile razy.
Dzięki za komentarz!
OdpowiedzUsuńChoć przyznam, że jednak nie do końca się z nim zgadzam, a dlaczego? Przeczytaj w nowym wpisie: WPF: o zasobach (resources) coś więcej.