Liên kết WPF với StringFormat không hoạt động trên ToolTips


87

Đoạn mã sau có một ràng buộc đơn giản liên kết Văn bản của TextBlock có tên MyTextBlock với thuộc tính Text và ToolTip của TextBox bằng cách sử dụng cùng một ký hiệu Binding:

<StackPanel>
    <TextBlock x:Name="MyTextBlock">Foo Bar</TextBlock>
    <TextBox    Text="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}"
             ToolTip="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}" />
</StackPanel>

Liên kết cũng sử dụng thuộc tính StringFormat được giới thiệu với .NET 3.5 SP1 đang hoạt động tốt đối với thuộc tính Văn bản ở trên nhưng dường như bị hỏng đối với Mẹo công cụ. Kết quả mong đợi là "It is: Foo Bar" nhưng khi bạn di chuột qua TextBox, ToolTip chỉ hiển thị giá trị ràng buộc chứ không phải giá trị được định dạng chuỗi. Có ý kiến ​​gì không?


3
Tôi không thể làm cho một trong hai giải pháp được đề xuất bên dưới hoạt động, nhưng giải pháp này đã hoạt động: stackoverflow.com/questions/4498649/…
17 of 26

Câu trả lời:


156

ToolTips trong WPF có thể chứa bất cứ thứ gì, không chỉ văn bản, vì vậy chúng cung cấp thuộc tính ContentStringFormat cho những lần bạn chỉ muốn văn bản. Bạn sẽ cần sử dụng cú pháp mở rộng theo như tôi biết:

<TextBox ...>
  <TextBox.ToolTip>
    <ToolTip 
      Content="{Binding ElementName=myTextBlock,Path=Text}"
      ContentStringFormat="{}It is: {0}"
      />
  </TextBox.ToolTip>
</TextBox>

Tôi không chắc chắn 100% về tính hợp lệ của việc ràng buộc bằng cú pháp ElementName từ một thuộc tính lồng nhau như vậy, nhưng thuộc tính ContentStringFormat là thứ bạn đang tìm kiếm.


1
Tôi hiểu rồi, tôi nghĩ ToolTip chỉ là một chuỗi đơn giản như trong Windows Forms. Và có, cú pháp ElementName trong trường hợp này không thể truy cập phần tử bên ngoài.
huseyint 13/10/08

9
Lưu ý rằng {} chỉ được yêu cầu khi bạn đặt {0} ở đầu chuỗi, vì vậy bạn cần nó để phân biệt với các đánh dấu xaml khác.
Shimmy Weitzhandler 12/12/09

5
Tâm = thổi. Tôi vừa nhấn cái này và giống như "waaaat?"

2
Tôi thực sự bực mình rằng định dạng chuỗi không 'chỉ hoạt động' khi không có trình chuyển đổi nào được chỉ định. Tôi đã phải viết stringformatConverter của riêng mình. MS thả bóng một lần nữa ...
Gusdor

3
StringFormatsẽ chỉ được áp dụng khi TargetTypelà loại chuỗi. ToolTipNội dung thuộc loại object.
Johannes Wanzek

22

Nó có thể là một lỗi. Khi bạn sử dụng cú pháp ngắn cho chú giải công cụ:

<TextBox ToolTip="{Binding WhatEverYouWant StringFormat='It is: \{0\}'}" />

StringFormat bị bỏ qua nhưng khi bạn sử dụng cú pháp mở rộng:

<TextBox Text="text">
   <TextBox.ToolTip>
      <TextBlock Text="{Binding WhatEverYouWant StringFormat='It is: \{0\}'}"/>
   </TextBox.ToolTip>
</TextBox>

Nó hoạt động như mong đợi.


Câu trả lời chính xác nhất .. Cảm ơn!
Amir Mahdi Nassiri

5

Như Matt đã nói ToolTip có thể chứa bất cứ thứ gì bên trong để bạn có thể liên kết TextBox.Text bên trong ToolTip của mình.

<StackPanel>
    <TextBlock x:Name="MyTextBlock">Foo Bar</TextBlock>
    <TextBox Text="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}">
        <TextBox.ToolTip>
            <TextBlock>
                <TextBlock.Text>
                    <Binding ElementName=MyTextBlock Path="Text" StringFormat="It is: {0}" />
                </TextBlock.Text>
            </TextBlock>
        </TextBox.ToolTip>
    </TextBox>
</StackPanel>

Thậm chí bạn có thể Xếp chồng một lưới bên trong ToolTip và bố trí văn bản của bạn nếu bạn muốn.


3

Mã của bạn có thể ngắn như sau:

<TextBlock ToolTip="{Binding PrideLands.YearsTillSimbaReturns,
    Converter={StaticResource convStringFormat},
    ConverterParameter='Rejoice! Just {0} years left!'}" Text="Hakuna Matata"/>

Chúng tôi sẽ sử dụng thực tế là các Chuyển đổi không bao giờ bị bỏ qua, không giống như StringFormat.

Đặt cái này vào StringFormatConverter.cs :

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace TLKiaWOL
{
    [ValueConversion (typeof(object), typeof(string))]
    public class StringFormatConverter : IValueConverter
    {
        public object Convert (object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (ReferenceEquals(value, DependencyProperty.UnsetValue))
                return DependencyProperty.UnsetValue;
            return string.Format(culture, (string)parameter, value);
        }

        public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
    }
}

Đặt cái này vào ResourceDictionary.xaml của bạn :

<conv:StringFormatConverter x:Key="convStringFormat"/>

Trong khi tôi thích câu trả lời hàng đầu, vấn đề ElementBinding đã khiến tôi vấp phải. Câu trả lời này phù hợp với trường hợp của tôi trong khi những người khác thì không.
Reginald Blue

0

Trong trường hợp này, bạn có thể sử dụng ràng buộc tương đối:

<StackPanel>
    <TextBlock x:Name="MyTextBlock">Foo Bar</TextBlock>
    <TextBox Text="{Binding ElementName=MyTextBlock, Path=Text, StringFormat='It is: \{0\}'}"
             ToolTip="{Binding Text, RelativeSource={RelativeSource Self}}" />
</StackPanel>

-7

Sau đây là một giải pháp dài dòng nhưng nó hoạt động.

<StackPanel>
  <TextBox Text="{Binding Path=., StringFormat='The answer is: {0}'}">
    <TextBox.DataContext>
      <sys:Int32>42</sys:Int32>
    </TextBox.DataContext>
    <TextBox.ToolTip>
      <ToolTip Content="{Binding}" ContentStringFormat="{}The answer is: {0}" />
    </TextBox.ToolTip>
  </TextBox>
</StackPanel>

Tôi thích một cú pháp đơn giản hơn nhiều, giống như cú pháp trong câu hỏi ban đầu của tôi.


1
@Shimmy: "tốt hơn" là trong mắt của khán giả, và không sao cả để đánh dấu câu hỏi của riêng bạn câu trả lời được chấp nhận
Andomar

1
@Shimmy Tồi tệ hơn nữa, câu trả lời của anh ấy bao gồm một trò đùa '42'.

6
@Andomar, tốt hơn là những gì mọi người quyết định với phiếu bầu của họ, cũng cụ thể ở đây, nó gần như chỉ có cùng một câu trả lời. bắt ppl trả lời câu hỏi của bạn sau đó sao chép câu trả lời của họ và tạo danh tiếng cho nó là một thái độ hoàn toàn sai lầm.
Shimmy Weitzhandler
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.