Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Poznámka:
Tento článek se týká rozhraní .NET Framework. Informace, které platí pro .NET 5 nebo novější (včetně .NET Core), najdete v tématu Prostředky v souborech .resx.
Vzhledem k tomu, že soubory prostředků XML (.resx) se musí skládat z dobře definovaného XML, včetně hlavičky, která musí dodržovat konkrétní schéma následované daty ve dvojicích name/value, můžete zjistit, že vytváření těchto souborů je náchylné k chybám. Jako alternativu můžete soubory .resx vytvářet programově pomocí typů a členů v knihovně tříd .NET. Knihovnu tříd .NET můžete použít také k získání prostředků uložených v souborech .resx. Tento článek vysvětluje, jak pomocí typů a členů v System.Resources oboru názvů pracovat se soubory .resx.
Tento článek popisuje práci se soubory XML (.resx), které obsahují prostředky. Informace o práci s binárními soubory prostředků, které byly vloženy do sestavení, naleznete v tématu ResourceManager.
Výstraha
Existují také způsoby, jak pracovat s jinými soubory .resx než programově. Když do projektu Visual Studio přidáte soubor prostředků, Visual Studio poskytuje rozhraní pro tvorbu a správu souboru .resx a automaticky převede soubor .resx na soubor .resources v době kompilace. K přímé manipulaci se souborem .resx můžete použít také textový editor. Chcete-li se však vyhnout poškození souboru, dávejte pozor, abyste neupravily žádné binární informace, které jsou uloženy v souboru.
Vytvoření souboru .resx
Můžete použít třídu System.Resources.ResXResourceWriter k programovému vytvoření souboru .resx podle následujících kroků:
ResXResourceWriter Vytvořte instanci objektu ResXResourceWriter(String) voláním metody a zadáním názvu souboru .resx. Název souboru musí obsahovat příponu .resx. Pokud vytvoříte instanci objektu ResXResourceWriter v bloku
using, nemusíte v kroku 3 explicitně volat metodu ResXResourceWriter.Close.Zavolejte metodu ResXResourceWriter.AddResource pro všechny prostředky, které chcete přidat do souboru. Přetížení této metody použijte k přidání řetězcových, objektových a binárních (bajtových polí) dat. Pokud je prostředek objektem, musí být serializovatelný.
Zavolejte metodu ResXResourceWriter.Close k vygenerování souboru prostředků a uvolnění všech prostředků. ResXResourceWriter Pokud byl objekt vytvořen v
usingrámci bloku, prostředky se zapisují do souboru .resx a prostředky používané objektem ResXResourceWriter se uvolní na konciusingbloku.
Výsledný soubor .resx má odpovídající hlavičku data a značku pro každý prostředek přidaný metodou ResXResourceWriter.AddResource .
Výstraha
Nepoužívejte soubory prostředků k ukládání hesel, citlivých informací o zabezpečení ani soukromých dat.
Následující příklad vytvoří soubor .resx s názvem CarResources.resx, který ukládá šest řetězců, ikonu a dva objekty definované aplikací (dva Automobile objekty). Třída Automobile , která je definována a vytvořena v příkladu, je označena atributem SerializableAttribute .
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
Návod
Pomocí Visual Studio můžete také vytvářet soubory .resx. Visual Studio v době kompilace používá generátor souborů prostředků (Resgen.exe) k převodu souboru .resx na binární soubor (.resources) a také ho vloží do sestavení aplikace nebo satelitního sestavení.
Soubor .resx nelze vložit do spustitelného souboru modulu runtime nebo jej zkompilovat do satelitního sestavení. Soubor .resx musíte převést na binární soubor prostředků (.resources) pomocí Generátoru souborů prostředků (Resgen.exe). Výsledný soubor .resources lze pak vložit do sestavení aplikace nebo satelitního sestavení. Další informace naleznete v Vytvoření souborů prostředků.
Vyjmenovat prostředky
V některých případech můžete ze souboru .resx chtít načíst všechny prostředky namísto konkrétního prostředku. K tomu můžete použít System.Resources.ResXResourceReader třídu, která poskytuje enumerátor pro všechny prostředky v souboru .resx. Třída System.Resources.ResXResourceReader implementuje IDictionaryEnumerator, který vrací DictionaryEntry objekt, který představuje specifický prostředek pro každou iteraci cyklu. Jeho DictionaryEntry.Key vlastnost vrátí klíč prostředku a jeho DictionaryEntry.Value vlastnost vrátí hodnotu prostředku.
Následující příklad vytvoří ResXResourceReader objekt pro soubor CarResources.resx vytvořený v předchozím příkladu a iteruje prostřednictvím souboru prostředků. Přidá dva Automobile objekty, které jsou definovány v souboru prostředků do System.Collections.Generic.List<T> objektu, a přidá pět z šesti řetězců k objektu SortedList . Hodnoty v objektu SortedList se převedou na pole parametrů, které slouží k zobrazení záhlaví sloupců v konzole. Hodnoty Automobile vlastností se také zobrazí v konzole.
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
Načtení konkrétního prostředku
Kromě vyčíslení položek v souboru .resx můžete pomocí třídy System.Resources.ResXResourceSet načíst konkrétní prostředek podle názvu. Metoda ResourceSet.GetString(String) načte hodnotu z pojmenovaného prostředku řetězce. Metoda ResourceSet.GetObject(String) načte hodnotu pojmenovaného objektu nebo binárních dat. Metoda vrátí objekt, který se pak musí přetypovat (v jazyce C#) nebo převést (v jazyce Visual Basic) na objekt příslušného typu.
Následující příklad získá text nadpisu formuláře a ikonu dle názvů prostředků. Načte také objekty definované Automobile aplikací použité v předchozím příkladu a zobrazí je v ovládacím DataGridView prvku.
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
Převod souborů .resx na binární soubory .resources
Převod souborů .resx na vložené soubory binárních prostředků (.resources) má významné výhody. I když jsou soubory .resx snadno čitelné a udržovat během vývoje aplikací, jsou zřídka zahrnuty do hotových aplikací. Pokud jsou distribuovány s aplikací, existují jako samostatné soubory kromě spustitelného souboru aplikace a jeho doprovodných knihoven. Naproti tomu soubory .resources jsou vloženy do spustitelného souboru aplikace nebo jeho doprovodných sestavení. Kromě toho, pokud jde o lokalizované aplikace, spoléhání na soubory .resx za běhu klade na vývojáře odpovědnost za zpracování záložních prostředků. Naproti tomu, pokud byla vytvořena sada satelitních sestavení, která obsahují vložené soubory .resources, společný modul CLR zpracovává proces záložních prostředků.
Chcete-li převést soubor .resx na soubor .resources , použijte Generátor souborů prostředků (resgen.exe), který má následující základní syntaxi:
resgen.exe .resxFilename
Výsledkem je binární soubor prostředků, který má stejný název kořenového souboru jako soubor .resx a příponu souboru .resources. Tento soubor je pak možné zkompilovat do spustitelného souboru nebo knihovny v době kompilace. Pokud používáte kompilátor jazyka Visual Basic, vložte do spustitelného souboru aplikace následující syntaxi:
vbc filename .vb -resource: .resourcesFilename
Pokud používáte jazyk C#, syntaxe je následující:
csc filename .cs -resource: .resourcesFilename
Soubor .resources lze také vložit do satelitního sestavení pomocí Assembly Linker (al.exe), který má následující základní syntaxi:
al resourcesFilename -out: assemblyFilename