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>












Maciej_Zbrzezny on delicious.com
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.