Nối các chuỗi thay vì sử dụng một chồng TextBlock


88

Tôi muốn hiển thị danh sách các đối tượng Khách hàng trong WPF ItemsControl. Tôi đã tạo một DataTemplate cho việc này:

    <DataTemplate DataType="{x:Type myNameSpace:Customer}">
        <StackPanel Orientation="Horizontal" Margin="10">
            <CheckBox"></CheckBox>
            <TextBlock Text="{Binding Path=Number}"></TextBlock>
            <TextBlock Text=" - "></TextBlock>
            <TextBlock Text="{Binding Path=Name}"></TextBlock>
        </StackPanel>
    </DataTemplate>

Vì vậy, những gì tôi muốn về cơ bản là một danh sách đơn giản (với các hộp kiểm) chứa SỐ - TÊN. Không có cách nào để tôi có thể ghép số và tên trực tiếp trong phần Ràng buộc?

Câu trả lời:


171

Có thuộc tính StringFormat (trong .NET 3.5 SP1) mà bạn có thể sử dụng. Và có thể tìm thấy vỏ bọc gian lận ràng buộc WPF hữu ích tại đây . Nếu nó không hữu ích, bạn luôn có thể viết ValueConverter của riêng bạn hoặc thuộc tính tùy chỉnh cho đối tượng của bạn.

Chỉ cần chọn, bạn có thể sử dụng StringFormat với đa liên kết. Trong trường hợp của bạn, mã sẽ như thế này:

<TextBlock>
  <TextBlock.Text>
    <MultiBinding StringFormat=" {0} - {1}">
        <Binding Path="Number"/>
        <Binding Path="Name"/>
    </MultiBinding>
  </TextBlock.Text>
</TextBlock>

Tôi phải bắt đầu chuỗi định dạng với khoảng trắng, nếu không thì Visual Studio sẽ không xây dựng, nhưng tôi nghĩ bạn sẽ tìm cách giải quyết nó :)

Chỉnh sửa Cần có
khoảng trống trong StringFormat để ngăn trình phân tích cú pháp coi {0}như một ràng buộc thực tế. Các lựa chọn thay thế khác:

<!-- use a space before the first format -->
<MultiBinding StringFormat=" {0} - {1}">

<!-- escape the formats -->
<MultiBinding StringFormat="\{0\} - \{1\}">

<!-- use {} before the first format -->
<MultiBinding StringFormat="{}{0} - {1}">

29
Thay vì khoảng trắng bạn có thể sử dụng {}, ví dụ: StringFormat = "{} {0} - {1}"
Bryan Anderson

6
Bạn cũng có thể thoát khỏi dấu ngoặc nhọn bằng dấu gạch chéo ngược: <MultiBinding StringFormat = "\ {0 \} - \ {1 \}">
hughdbrown 17/02/09

Ngoài ra, TextBlock đóng bị thiếu, vì vậy để tóm tắt các nhận xét: <TextBlock> <TextBlock.Text> <MultiBinding StringFormat = "{} {0} - {1}"> <Binding Path = "Number" /> <Binding Path = "Name" /> </MultiBinding> </TextBlock.Text> </TextBlock>
TJKjaer

@PiRX nếu tôi muốn hiển thị 'số' ngay cả khi 'tên' trống - làm cách nào để làm điều đó?
DasDas

@DasDas Rất tiếc, tôi sẽ không thể trợ giúp câu hỏi của bạn vì tôi đã không làm việc với WPF trong vài năm. Thật buồn cười khi bạn quên nhanh những thứ bạn không làm việc nữa.
PiRX

64

Trong trường hợp bạn muốn nối giá trị động với văn bản tĩnh, hãy thử cách này:

<TextBlock Text="{Binding IndividualSSN, StringFormat= '\{0\} (SSN)'}"/>

Hiển thị : 234-334-5566 (SSN)


1
Nội dung của TextBlockLeftStyle là gì?
itho

Đó là một phong cách tùy chỉnh mà tôi phải căn chỉnh khối văn bản sang trái. Nó không có ý nghĩa ở đây.
redskull

1
Đây là giải pháp tốt nhất để nối một ràng buộc với một chuỗi
Devid

8

Xem ví dụ sau mà tôi đã sử dụng trong mã của mình bằng Run class:

        <TextBlock x:Name="..." Width="..." Height="..."
            <Run Text="Area="/>
            <Run Text="{Binding ...}"/>
            <Run Text="sq.mm"/>
            <LineBreak/>
            <Run Text="Min Diameter="/>
            <Run Text="{Binding...}"/>
            <LineBreak/>
            <Run Text="Max Diameter="/>
            <Run Text="{Binding...}"/>
        </TextBlock >

3

Bạn cũng có thể sử dụng một lần chạy có thể ràng buộc. Nội dung hữu ích, đặc biệt nếu người ta muốn thêm một số định dạng văn bản (màu sắc, độ đậm phông chữ, v.v.).

<TextBlock>
   <something:BindableRun BoundText="{Binding Number}"/>
   <Run Text=" - "/>
   <something:BindableRun BoundText="{Binding Name}"/>
</TextBlock>

Đây là một lớp ban đầu:
Đây là một số cải tiến bổ sung.
Và đó là tất cả trong một đoạn mã:

public class BindableRun : Run
    {
        public static readonly DependencyProperty BoundTextProperty = DependencyProperty.Register("BoundText", typeof(string), typeof(BindableRun), new PropertyMetadata(new PropertyChangedCallback(BindableRun.onBoundTextChanged)));

        private static void onBoundTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((Run)d).Text = (string)e.NewValue;
        }

        public String BoundText
        {
            get { return (string)GetValue(BoundTextProperty); }
            set { SetValue(BoundTextProperty, value); }
        }

        public BindableRun()
            : base()
        {
            Binding b = new Binding("DataContext");
            b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(FrameworkElement), 1);
            this.SetBinding(DataContextProperty, b);
        }
    }

1
<Chạy Text = "{Binding ...}" />? Bạn có thể giải thích những lợi thế?
Felix Keil

1
Không khác nhau; Run không hỗ trợ ràng buộc trên thuộc tính Text 10 năm trước khi câu trả lời này được viết!
josh2112
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.