Megosztás a következőn keresztül:


A .resx-fájlok programozott működése

Feljegyzés

Ez a cikk a .NET-keretrendszer vonatkozik. A .NET 5+ verzióra (beleértve a .NET Core-t is) vonatkozó információkért tekintse meg a .resx fájlok erőforrásait.

Mivel az XML-erőforrásfájloknak (.resx) jól definiált XML-fájlokból kell állniuk, beleértve egy fejlécet is, amelynek egy adott sémát kell követnie, majd a név-érték párokban szereplő adatokat, előfordulhat, hogy a fájlok manuális létrehozása hibalehetőséget jelent. Alternatív megoldásként programozott módon is létrehozhat .resx fájlokat a .NET osztálytár típusok és tagok használatával. A .NET-osztálytár használatával is lekérheti a .resx fájlokban tárolt erőforrásokat. Ez a cikk bemutatja, hogyan használhatja a névtérben lévő típusokat és tagokat a System.Resources .resx fájlok használatához.

Ez a cikk az erőforrásokat tartalmazó XML-fájlok (.resx) használatát ismerteti. A szerelvényekbe beágyazott bináris erőforrásfájlok használatával kapcsolatos információkért lásd: ResourceManager.

Figyelmeztetés

A .resx-fájlokat programozott módon kívül más módon is kezelheti. Amikor erőforrásfájlt ad hozzá egy Visual Studio-projekthez , a Visual Studio felületet biztosít egy .resx-fájl létrehozásához és karbantartásához, és fordításkor automatikusan .resources fájllá alakítja a .resx fájlt. A .resx fájlokat közvetlenül szövegszerkesztővel is módosíthatja. A fájl sérülésének elkerülése érdekében azonban ügyeljen arra, hogy ne módosítsa a fájlban tárolt bináris adatokat.

.resx fájl létrehozása

Az System.Resources.ResXResourceWriter osztály segítségével programozott módon hozhat létre .resx fájlt az alábbi lépések végrehajtásával:

  1. Példányosíthat egy ResXResourceWriter objektumot a ResXResourceWriter(String) metódus meghívásával és a .resx fájl nevének megadásával. A fájlnévnek tartalmaznia kell a .resx kiterjesztést. Ha egy using blokkban példányosít ResXResourceWriter egy objektumot, nem kell explicit módon meghívnia a metódust a ResXResourceWriter.Close 3. lépésben.

  2. Hívja meg a ResXResourceWriter.AddResource fájlhoz hozzáadni kívánt összes erőforrás metódusát. A metódus túlterhelésével sztring-, objektum- és bináris (bájttömb) adatokat adhat hozzá. Ha az erőforrás objektum, akkor szerializálhatónak kell lennie.

  3. ResXResourceWriter.Close Az erőforrásfájl létrehozásához és az összes erőforrás kiadásához hívja meg a metódust. Ha az ResXResourceWriter objektum egy using blokkon belül jött létre, a rendszer az erőforrásokat a .resx fájlba írja, és az ResXResourceWriter objektum által használt erőforrások a blokk végén using lesznek felszabadítva.

Az eredményként kapott .resx fájl rendelkezik a megfelelő fejléccel és címkével data a ResXResourceWriter.AddResource metódus által hozzáadott egyes erőforrásokhoz.

Figyelmeztetés

Ne használjon erőforrásfájlokat jelszavak, biztonsági bizalmas adatok vagy személyes adatok tárolására.

Az alábbi példa egy CarResources.resx nevű .resx fájlt hoz létre, amely hat sztringet, egy ikont és két alkalmazás által definiált objektumot (két Automobile objektumot) tárol. A Automobile példában definiált és példányosított osztály az attribútummal SerializableAttribute van megjelölve.

using System;
using System.Drawing;
using System.Resources;

[Serializable()] public class Automobile
{
   private string carMake;
   private string carModel;
   private int carYear;
   private int carDoors;
   private int carCylinders;

   public Automobile(string make, string model, int year) :
                     this(make, model, year, 0, 0)
   { }

   public Automobile(string make, string model, int year,
                     int doors, int cylinders)
   {
      this.carMake = make;
      this.carModel = model;
      this.carYear = year;
      this.carDoors = doors;
      this.carCylinders = cylinders;
   }

   public string Make {
      get { return this.carMake; }
   }

   public string Model {
      get {return this.carModel; }
   }

   public int Year {
      get { return this.carYear; }
   }

   public int Doors {
      get { return this.carDoors; }
   }

   public int Cylinders {
      get { return this.carCylinders; }
   }
}

public class Example
{
   public static void Main()
   {
      // Instantiate an Automobile object.
      Automobile car1 = new Automobile("Ford", "Model N", 1906, 0, 4);
      Automobile car2 = new Automobile("Ford", "Model T", 1909, 2, 4);
      // Define a resource file named CarResources.resx.
      using (ResXResourceWriter resx = new ResXResourceWriter(@".\CarResources.resx"))
      {
         resx.AddResource("Title", "Classic American Cars");
         resx.AddResource("HeaderString1", "Make");
         resx.AddResource("HeaderString2", "Model");
         resx.AddResource("HeaderString3", "Year");
         resx.AddResource("HeaderString4", "Doors");
         resx.AddResource("HeaderString5", "Cylinders");
         resx.AddResource("Information", SystemIcons.Information);
         resx.AddResource("EarlyAuto1", car1);
         resx.AddResource("EarlyAuto2", car2);
      }
   }
}
Imports System.Drawing
Imports System.Resources

<Serializable()> Public Class Automobile
    Private carMake As String
    Private carModel As String
    Private carYear As Integer
    Private carDoors AS Integer
    Private carCylinders As Integer

    Public Sub New(make As String, model As String, year As Integer)
        Me.New(make, model, year, 0, 0)
    End Sub

    Public Sub New(make As String, model As String, year As Integer,
                   doors As Integer, cylinders As Integer)
        Me.carMake = make
        Me.carModel = model
        Me.carYear = year
        Me.carDoors = doors
        Me.carCylinders = cylinders
    End Sub

    Public ReadOnly Property Make As String
        Get
            Return Me.carMake
        End Get
    End Property

    Public ReadOnly Property Model As String
        Get
            Return Me.carModel
        End Get
    End Property

    Public ReadOnly Property Year As Integer
        Get
            Return Me.carYear
        End Get
    End Property

    Public ReadOnly Property Doors As Integer
        Get
            Return Me.carDoors
        End Get
    End Property

    Public ReadOnly Property Cylinders As Integer
        Get
            Return Me.carCylinders
        End Get
    End Property
End Class

Module Example
    Public Sub Main()
        ' Instantiate an Automobile object.
        Dim car1 As New Automobile("Ford", "Model N", 1906, 0, 4)
        Dim car2 As New Automobile("Ford", "Model T", 1909, 2, 4)
        ' Define a resource file named CarResources.resx.
        Using resx As New ResXResourceWriter(".\CarResources.resx")
            resx.AddResource("Title", "Classic American Cars")
            resx.AddResource("HeaderString1", "Make")
            resx.AddResource("HeaderString2", "Model")
            resx.AddResource("HeaderString3", "Year")
            resx.AddResource("HeaderString4", "Doors")
            resx.AddResource("HeaderString5", "Cylinders")
            resx.AddResource("Information", SystemIcons.Information)
            resx.AddResource("EarlyAuto1", car1)
            resx.AddResource("EarlyAuto2", car2)
        End Using
    End Sub
End Module

Tipp.

A Visual Studióval .resx fájlokat is létrehozhat. Fordításkor a Visual Studio az erőforrásfájl-generátorral (Resgen.exe) bináris erőforrásfájllá (.resources) konvertálja a .resx fájlt, és beágyazza egy alkalmazásszerelvénybe vagy egy műholdas szerelvénybe is.

A .resx fájlokat nem ágyazhatja be futtatókörnyezetbe, és nem fordíthatja azt műholdas szerelvénybe. A .resx fájlt bináris erőforrásfájllá (.resources) kell konvertálnia az erőforrásfájl-generátor (Resgen.exe) használatával. Az eredményül kapott .resources fájl ezután beágyazható egy alkalmazásszerelvénybe vagy egy műholdas szerelvénybe. További információ: Erőforrásfájlok létrehozása.

Erőforrások számbavétele

Bizonyos esetekben előfordulhat, hogy az összes erőforrást egy .resx fájlból szeretné lekérni egy adott erőforrás helyett. Ehhez használhatja az System.Resources.ResXResourceReader osztályt, amely enumerátort biztosít a .resx fájl összes erőforrásához. Az System.Resources.ResXResourceReader osztály implementál IDictionaryEnumeratoregy DictionaryEntry objektumot, amely egy adott erőforrást jelöl a ciklus egyes iterációihoz. A DictionaryEntry.Key tulajdonság visszaadja az erőforrás kulcsát, a tulajdonsága DictionaryEntry.Value pedig az erőforrás értékét.

Az alábbi példa létrehoz egy ResXResourceReader objektumot az előző példában létrehozott CarResources.resx fájlhoz, és iterálja az erőforrásfájlt. Hozzáadja az erőforrásfájlban definiált két Automobile objektumot egy System.Collections.Generic.List<T> objektumhoz, és a hat sztringből ötöt hozzáad egy SortedList objektumhoz. Az objektum értékei SortedList paramétertömbré alakulnak, amely a konzolon lévő oszlopfejlécek megjelenítésére szolgál. A Automobile tulajdonságértékek a konzolon is megjelennek.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Resources;

public class Example
{
   public static void Main()
   {
      string resxFile = @".\CarResources.resx";
      List<Automobile> autos = new List<Automobile>();
      SortedList headers = new SortedList();

      using (ResXResourceReader resxReader = new ResXResourceReader(resxFile))
      {
         foreach (DictionaryEntry entry in resxReader) {
            if (((string) entry.Key).StartsWith("EarlyAuto"))
               autos.Add((Automobile) entry.Value);
            else if (((string) entry.Key).StartsWith("Header"))
               headers.Add((string) entry.Key, (string) entry.Value);
         }
      }
      string[] headerColumns = new string[headers.Count];
      headers.GetValueList().CopyTo(headerColumns, 0);
      Console.WriteLine("{0,-8} {1,-10} {2,-4}   {3,-5}   {4,-9}\n",
                        headerColumns);
      foreach (var auto in autos)
         Console.WriteLine("{0,-8} {1,-10} {2,4}   {3,5}   {4,9}",
                           auto.Make, auto.Model, auto.Year,
                           auto.Doors, auto.Cylinders);
   }
}
// The example displays the following output:
//       Make     Model      Year   Doors   Cylinders
//
//       Ford     Model N    1906       0           4
//       Ford     Model T    1909       2           4
Imports System.Collections
Imports System.Collections.Generic
Imports System.Resources

Module Example
    Public Sub Main()
        Dim resxFile As String = ".\CarResources.resx"
        Dim autos As New List(Of Automobile)
        Dim headers As New SortedList()

        Using resxReader As New ResXResourceReader(resxFile)
            For Each entry As DictionaryEntry In resxReader
                If CType(entry.Key, String).StartsWith("EarlyAuto") Then
                    autos.Add(CType(entry.Value, Automobile))
                Else If CType(entry.Key, String).StartsWith("Header") Then
                    headers.Add(CType(entry.Key, String), CType(entry.Value, String))
                End If
            Next
        End Using
        Dim headerColumns(headers.Count - 1) As String
        headers.GetValueList().CopyTo(headerColumns, 0)
        Console.WriteLine("{0,-8} {1,-10} {2,-4}   {3,-5}   {4,-9}",
                          headerColumns)
        Console.WriteLine()
        For Each auto In autos
            Console.WriteLine("{0,-8} {1,-10} {2,4}   {3,5}   {4,9}",
                              auto.Make, auto.Model, auto.Year,
                              auto.Doors, auto.Cylinders)
        Next
    End Sub
End Module
' The example displays the following output:
'       Make     Model      Year   Doors   Cylinders
'       
'       Ford     Model N    1906       0           4
'       Ford     Model T    1909       2           4

Adott erőforrás lekérése

A .resx fájl elemeinek számbavétele mellett az osztály használatával név szerint is lekérhet egy adott erőforrást System.Resources.ResXResourceSet . A ResourceSet.GetString(String) metódus lekéri egy elnevezett sztringerőforrás értékét. A ResourceSet.GetObject(String) metódus lekéri egy elnevezett objektum vagy bináris adat értékét. A metódus egy olyan objektumot ad vissza, amelyet ezután el kell vetíteni (C#-ban) vagy konvertálni (a Visual Basicben) egy megfelelő típusú objektummá.

Az alábbi példa lekéri egy űrlap képaláírás sztringjét és ikonját az erőforrásnevük alapján. Emellett lekéri az előző példában használt alkalmazás által definiált Automobile objektumokat, és megjeleníti őket egy DataGridView vezérlőben.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Resources;
using System.Windows.Forms;

public class CarDisplayApp : Form
{
   private const string resxFile = @".\CarResources.resx";
   Automobile[] cars;

   public static void Main()
   {
      CarDisplayApp app = new CarDisplayApp();
      Application.Run(app);
   }

   public CarDisplayApp()
   {
      // Instantiate controls.
      PictureBox pictureBox = new PictureBox();
      pictureBox.Location = new Point(10, 10);
      this.Controls.Add(pictureBox);
      DataGridView grid = new DataGridView();
      grid.Location = new Point(10, 60);
      this.Controls.Add(grid);

      // Get resources from .resx file.
      using (ResXResourceSet resxSet = new ResXResourceSet(resxFile))
      {
         // Retrieve the string resource for the title.
         this.Text = resxSet.GetString("Title");
         // Retrieve the image.
         Icon image = (Icon) resxSet.GetObject("Information", true);
         if (image != null)
            pictureBox.Image = image.ToBitmap();

         // Retrieve Automobile objects.
         List<Automobile> carList = new List<Automobile>();
         string resName = "EarlyAuto";
         Automobile auto;
         int ctr = 1;
         do {
            auto = (Automobile) resxSet.GetObject(resName + ctr.ToString());
            ctr++;
            if (auto != null)
               carList.Add(auto);
         } while (auto != null);
         cars = carList.ToArray();
         grid.DataSource = cars;
      }
   }
}
Imports System.Collections.Generic
Imports System.Drawing
Imports System.Resources
Imports System.Windows.Forms

Public Class CarDisplayApp : Inherits Form
    Private Const resxFile As String = ".\CarResources.resx"
    Dim cars() As Automobile

    Public Shared Sub Main()
        Dim app As New CarDisplayApp()
        Application.Run(app)
    End Sub

    Public Sub New()
        ' Instantiate controls.
        Dim pictureBox As New PictureBox()
        pictureBox.Location = New Point(10, 10)
        Me.Controls.Add(pictureBox)
        Dim grid As New DataGridView()
        grid.Location = New Point(10, 60)
        Me.Controls.Add(grid)

        ' Get resources from .resx file.
        Using resxSet As New ResXResourceSet(resxFile)
            ' Retrieve the string resource for the title.
            Me.Text = resxSet.GetString("Title")
            ' Retrieve the image.
            Dim image As Icon = CType(resxSet.GetObject("Information", True), Icon)
            If image IsNot Nothing Then
                pictureBox.Image = image.ToBitmap()
            End If

            ' Retrieve Automobile objects.  
            Dim carList As New List(Of Automobile)
            Dim resName As String = "EarlyAuto"
            Dim auto As Automobile
            Dim ctr As Integer = 1
            Do
                auto = CType(resxSet.GetObject(resName + ctr.ToString()), Automobile)
                ctr += 1
                If auto IsNot Nothing Then carList.Add(auto)
            Loop While auto IsNot Nothing
            cars = carList.ToArray()
            grid.DataSource = cars
        End Using
    End Sub
End Class

.resx fájlok konvertálása bináris .resources fájlokká

A .resx fájlok konvertálása beágyazott bináris erőforrásfájlokká (.resources) jelentős előnyökkel jár. Bár a .resx fájlok könnyen olvashatók és karbantarthatóak az alkalmazásfejlesztés során, ritkán szerepelnek a kész alkalmazásokban. Ha egy alkalmazással vannak elosztva, az alkalmazás végrehajtható fájljaitól és a hozzá tartozó kódtáraktól eltekintve különálló fájlokként léteznek. Ezzel szemben a .resources fájlok az alkalmazás végrehajtható vagy a hozzá tartozó szerelvényekbe vannak beágyazva. Emellett a honosított alkalmazások esetében a .resx fájlok futásidőben történő támaszkodása a fejlesztőre bízza az erőforrás-tartalék kezelésének felelősségét. Ezzel szemben, ha beágyazott .resources fájlokat tartalmazó műholdas szerelvényeket hoztak létre, a közös nyelvi futtatókörnyezet kezeli az erőforrás-tartalék folyamatot.

A .resx fájl .resources fájllá alakításához az erőforrásfájl-generátort (resgen.exe) kell használnia, amely az alábbi alapszintaxissal rendelkezik:

 resgen.exe .resxFilename

Az eredmény egy bináris erőforrásfájl, amelynek gyökérfájlneve megegyezik a .resx fájl és a .resources fájlkiterjesztés nevével. Ez a fájl ezután lefordítható végrehajtható vagy tárba fordításkor. Ha a Visual Basic fordítót használja, az alábbi szintaxissal ágyazhat be egy .resources-fájlt egy alkalmazás végrehajtható fájljában:

vbc filename .vb -resource: .resourcesFilename

Ha C#-ot használ, a szintaxis a következő:

 csc filename .cs -resource: .resourcesFilename

A .resources fájl a Assembly Linker (al.exe) használatával is beágyazható egy műholdas szerelvénybe, amely az alábbi alapvető szintaxissal rendelkezik:

al resourcesFilename -out: assemblyFilename

Lásd még