2009-03-20 40 views
10

Tôi có một ứng dụng XBAP với điều khiển người dùng sau:Làm thế nào để lấy chuỗi từ tài nguyên để gán trong phần WPF tài nguyên trong XAML

<UserControl x:Class="XXX.UsersGrid" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Height="Auto" Width="Auto"> 

     <UserControl.Resources> 
      <DataTemplate x:Key="UpArrowUsers"> 
       <DockPanel> 
        <TextBlock Text="xxUser" x:Name="upArrowUsersHeader" HorizontalAlignment="Center"></TextBlock> 
        <Path x:Name="arrow" StrokeThickness = "1" Fill= "gray" Data= "M 5,10 L 15,10 L 10,5 L 5,10"/> 
       </DockPanel> 
      </DataTemplate> 
    </UserControl> 
    ... 

Bây giờ tôi muốn lấy chuỗi "xxUser" từ một file resx mà được nhúng làm tài nguyên trong ứng dụng Làm cách nào để đạt được điều này?

Trả lời

3

Không có câu trả lời nào gần với những gì bạn muốn. Tôi sẽ bắt đầu bằng cách đọc về Bản địa hóa trong WPF. Bạn sẽ thấy rằng nếu bạn đang làm nội địa hóa với WPF bạn sẽ muốn x: Uid được định nghĩa trên mỗi nút trong ứng dụng của bạn.

http://msdn.microsoft.com/en-us/library/ms788718.aspx

+7

Tôi vui vì nó đã giúp poster ban đầu, nhưng thường mục đích của diễn đàn là thêm một cái gì đó vào tài liệu chính thức. Chỉ cần 2 xu của tôi. – greenoldman

0

Tôi không biết nếu điều này có thể được thực hiện trực tiếp trong XAML nhưng nếu bạn viết lớp trình bao bọc của riêng bạn quanh ResourceManager và sử dụng nó thay thế. Chú ý rằng các lớp kế thừa từ TextBlock:

public class ResourceContentTextBlock : TextBlock 
{ 
    public string ResourceName 
    { 
     set 
     { 
      this.Text = Properties.Resources.ResourceManager.GetString(value); 
     } 
    } 
} 

Sau đó bạn có thể sử dụng ResourceContentTextBlock trong XAML của bạn bất cứ nơi nào bạn nếu không sẽ sử dụng một TextBlock:

<Window x:Class="WpfApplication3.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:client="clr-namespace:WpfApplication3" 
    > 
     <client:ResourceContentTextBlock ResourceName="String1" /> 
</Window> 
+0

Tôi đang bối rối bởi điều này. Những gì đang xảy ra ở đây? Tại sao bạn đã xác định một setter, nhưng không có getter? Và làm các literals "String1" trong C# và XAML có bất kỳ kết nối? Vui lòng làm rõ. –

+0

Bạn nói đúng - Tôi phải thừa nhận đây là một câu trả lời khủng khiếp với một vài lỗi. Tôi đã thực hiện một vài cơ hội để sửa nó nhưng nó là một giải pháp rườm rà. Ý tưởng là thuộc tính ResourceName được đặt thành "String1" trong XAML. ResourceContentTextBlock sử dụng giá trị này để tìm nạp một chuỗi được bản địa hóa từ các tài nguyên và cập nhật thuộc tính Text của TextBox kế thừa. Đó là lý do tại sao không cần phải có tài sản. –

5

Tạo một lớp tĩnh mà làm cho các nguồn lực sẵn có như tài sản:

public static class Resources 
{ 
    public string Resource 
    { 
     return Properties.Resources.ResourceManager.GetString("Resource"); 
    } 
} 

Sau đó, bạn có thể ràng buộc TextBox của bạn như thế này:

<TextBlock Text="{Binding Source={x:Static local:Resources}, Path=Resource}" x:Name="upArrowUsersHeader" HorizontalAlignment="Center" 
    xmlns:local="clr-namespace:MY_NAMESPACE;assembly=MY_ASSEMBLY"> 
42

tôi đã có thể làm điều đó trong một chương trình với:

<TextBlock VerticalAlignment="Center" Margin="3" 
      Text="{x:Static prop:Resources.OpenButton}" 
      Visibility="{Binding Source={x:Static prop:Settings.Default}, Path=ShowButtonText, Converter={StaticResource BoolToVis}}"></TextBlock> 

Tôi cũng đã phải bao gồm không gian tên .properties trong XAML của tôi, như vậy:

xmlns:prop="clr-namespace:MyProjectNamespace.Properties" 

Điều này cho phép tôi không chỉ sử dụng tài nguyên chuỗi mà tôi đã xác định cho dự án của mình cho toàn cầu hóa, nhưng tôi cũng có thể liên kết (hai chiều) với Cài đặt của ứng dụng của tôi. Điều này cho phép tôi rất dễ dàng nhớ vị trí, kích thước của cửa sổ, v.v. Như bạn thấy, hãy sử dụng Cài đặt. cho cài đặt và Tài nguyên. cho tài nguyên. Như Steven đã đề cập, tôi nghĩ cách "chính thức" hoặc cách "tốt nhất" là gắn x: Uid lên mọi thứ mà bạn muốn toàn cầu hóa, nhưng tôi đã không làm việc đó mà không có vấn đề gì. Tôi nghĩ rằng điều x: Uid chủ yếu được yêu cầu nếu bạn đang sử dụng các công cụ tự động hoặc phá vỡ nhiệm vụ dịch thuật như bạn làm trong một dự án lớn. Tôi chỉ làm tất cả các công cụ của riêng mình bằng tay trong VS, vì vậy có lẽ nó là ok.

Bến

+0

Cảm ơn bạn VERY MUCH cho câu trả lời hữu ích và thông tin này. Nó đã giúp tôi rất nhiều - đó là phần còn thiếu cuối cùng trong dự án của tôi :-) Tôi chỉ nhầm lẫn với Tài nguyên - chúng phải được xác định thông qua Thuộc tính của dự án, không phải bởi "Add -> New Item -> Resources", đúng? – greenoldman

9

Hai điểm thêm nữa mà tôi quên đề cập đến ở trên trong "Tôi đã có thể làm điều đó ...":

  1. Bạn không cần phải quấn đối tượng Properties.Resources trong của riêng bạn. Bạn có thể truy cập trực tiếp, như tôi đã làm trong ví dụ trên. Tôi nghĩ rằng bao bọc đối tượng là một cách để có được kết quả tương tự như tôi thảo luận ở điểm thứ 2 của tôi.
  2. Theo mặc định, tệp tài nguyên được tạo bằng "ResXFileCodeGenerator". Điều này làm cho chúng nội bộ khi nó tạo ra tệp mã, vì vậy xaml không thể truy cập nó. Bạn phải thay đổi điều này thành "PublicResXFileCodeGenerator", tạo lớp học công khai.Bạn có thể thay đổi điều này bằng cách nhấp vào tệp tài nguyên trong trình khám phá giải pháp và chỉnh sửa thuộc tính "Công cụ tùy chỉnh".

(xin lỗi, tôi không thể chỉnh sửa bài viết ở trên của tôi, vì tôi là một thành viên tạm thời lúc bấy giờ.)

+3

ad.2. Đây là thiếu sót phổ biến (ngạc nhiên), VS cho phép bạn chỉ cần chuyển sang combo "công khai" ("access modifier" trong thanh công cụ). Không cần công cụ của bên thứ ba. – greenoldman

+0

Cảm ơn cho tip này, tôi đã cố gắng tìm ra lý do tại sao tài nguyên của tôi đã được thiết lập để nội bộ và không thể được sử dụng ... tại sao không phải là một lĩnh vực thả xuống trong Visual Studio? : \ – John

4

Như Ben nói, và tôi thấy an another tutorial. Các access modifier của Resources.resx phải được thay đổi từ Internal thành Public. Tôi đã thất bại nhiều lần và sau khi thay đổi access modifier thành Public, nó hoạt động.

Các vấn đề liên quan