WPF StringFormat trên nội dung nhãn


77

Tôi muốn định dạng ràng buộc chuỗi của mình Amount is Xở đâuX là một tài sản bị ràng buộc vào một nhãn.

Tôi đã xem nhiều ví dụ nhưng cách sau không hoạt động:

<Label Content="{Binding Path=MaxLevelofInvestment, 
   StringFormat='Amount is {0}'}" />

Tôi cũng đã thử các kết hợp sau:

StringFormat=Amount is {0}
StringFormat='Amount is {}{0}'
StringFormat='Amount is \{0\}'

Tôi thậm chí đã thử thay đổi kiểu dữ liệu của thuộc tính ràng buộc thành int, stringdouble. Dường như không có gì hoạt động. Đây là một trường hợp sử dụng rất phổ biến nhưng dường như không được hỗ trợ.

Câu trả lời:


205

Lý do điều này không hoạt động là thuộc Label.Contenttính thuộc loại ObjectBinding.StringFormatchỉ được sử dụng khi liên kết với thuộc tính của loại String.

Điều gì đang xảy ra là:

  1. Các Bindingbị đấm bốc của bạn MaxLevelOfInvestmentgiá trị và lưu trữ nó trở thành Label.Contenttài sản như một giá trị thập phân đóng hộp.
  2. Điều khiển Nhãn có một mẫu bao gồm a ContentPresenter.
  3. ContentTemplatekhông được đặt, hãy ContentPresentertìm một DataTemplateđịnh nghĩa cho Decimalloại. Khi không tìm thấy, nó sử dụng một mẫu mặc định.
  4. Mẫu mặc định được các ContentPresenterchuỗi trình bày sử dụng bằng cách sử dụng thuộc tính của nhãn ContentStringFormat.

Có thể có hai giải pháp:

  • Sử dụng Label.ContentStringFormat thay vì Binding.StringFormat, hoặc
  • Sử dụng thuộc tính String như TextBlock.Text thay vì Label.Content

Đây là cách sử dụng Label.ContentStringFormat:

<Label Content="{Binding Path=MaxLevelofInvestment}" ContentStringFormat="Amount is {0}" />

Đây là cách sử dụng TextBlock:

<TextBlock Text="{Binding Path=MaxLevelofInvestment, StringFormat='Amount is {0}'}" />

Lưu ý: Để đơn giản hơn, tôi đã bỏ qua một chi tiết trong phần giải thích ở trên: Thực ContentPresentersự sử dụng thuộc tính Templatevà của riêng nó StringFormat, nhưng trong quá trình tải, chúng tự động bị ràng buộc bởi mẫu với các thuộc tính ContentTemplateContentStringFormatcủa Label, vì vậy có vẻ như ContentPresenterthực sự đang sử dụng Labelthuộc tính của .


cảm ơn cho lời giải thích chi tiết, bây giờ nó có ý nghĩa. lên đến nhóm WPF để làm cho điều này trở nên gọn gàng cho tương lai.
Mọi thứ đều quan trọng,

Tôi thích câu trả lời của bạn, bạn có biết cách sử dụng 2 tham số thay vì chỉ 1 không? Thực sự gặp khó khăn ở đây (như TextBlock stringFormat có thể xử lý nhiều khi sử dụng trình kích hoạt, v.v.).
EricG

Tại sao trong trường hợp này, bạn cần đặt Path = trước ràng buộc của mình? bình thường tôi có thể làm Content="{Binding MaxLevelofInvestment}"và nó hoạt động tốt ...
MistaGoustan

6
Đối với hậu thế: nếu bạn bắt đầu ContentStringFormat bằng một {0}, đừng quên đặt {}trước nó. Vì vậy, hãy làm cho nóContentStringFormat="{}{0} some text here"
jep

7

Làm cho một phổ quát StringFormatConverter : IValueConverter. Chuyển chuỗi định dạng của bạn dưới dạng ConverterParameter.

Label Content="{Binding Amount, Converter={...myConverter}, ConverterParameter='Amount is {0}'"

Ngoài ra, hãy thực hiện StringFormatMultiConverter : IMultiValueConverterkhi bạn cần nhiều hơn một đối tượng trong chuỗi định dạng, chẳng hạn Completed {0} tasks out of {1}.


Tôi thích điều này. Tôi có thể thấy giá trị của việc sử dụng cả XAMLphương pháp tiếp cận thuần túy hoặc công cụ chuyển đổi giá trị.
IAbstract

4

Tôi vừa kiểm tra và vì một số lý do mà nó không hoạt động với Nhãn, có thể là do nó sử dụng ContentPresenter cho thuộc tính Nội dung bên trong. Bạn có thể sử dụng TextBlock để thay thế và điều đó sẽ hoạt động. Bạn cũng có thể đặt đoạn trích TextBlock bên dưới vào nội dung của Nhãn nếu bạn cần kế thừa kiểu, hành vi, v.v.

<TextBlock Text="{Binding Path=MaxLevelofInvestment, StringFormat='Amount is \{0\}'} />

1

Hãy thử sử dụng công cụ chuyển đổi ....

<myconverters:MyConverter x:Key="MyConverter"/>


<Label Content="{Binding Path=MaxLevelofInvestment, Converter={StaticResource MyConverter"} />


public class MyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return String.Format("Amount is {0}", value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value;
    }
}

4
Nó là quá mức cần thiết. Tôi giải thích nguyên nhân của vấn đề và trình bày hai giải pháp đơn giản trong câu trả lời của tôi.
Ray Burns

Tôi đồng ý rằng điều này ẩn việc sử dụng, gần đây tôi đã kế thừa một dự án mà cách tiếp cận này đã được thực hiện và các nhà phát triển muốn sử dụng bản dựng trong StringFormat hơn là cuộn của riêng họ.
Fermin

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.