การผูก WPF กับ StringFormat ไม่ทำงานบน ToolTips


88

รหัสต่อไปนี้มีการผูกแบบง่ายซึ่งผูก Text ของ TextBlock ชื่อ MyTextBlock กับคุณสมบัติ Text และ ToolTip ของ TextBox โดยใช้สัญกรณ์การผูกเดียวกันทุกประการ:

<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>

การรวมยังใช้คุณสมบัติ StringFormat ที่นำมาใช้กับ. NET 3.5 SP1ซึ่งทำงานได้ดีสำหรับคุณสมบัติข้อความข้างต้น แต่ดูเหมือนจะใช้งานไม่ได้สำหรับ ToolTip ผลลัพธ์ที่คาดไว้คือ "It is: Foo Bar" แต่เมื่อคุณวางเมาส์เหนือ TextBox ToolTip จะแสดงเฉพาะค่าการผูกไม่ใช่ค่าที่จัดรูปแบบสตริง ความคิดใด ๆ ?


3
ฉันไม่สามารถรับโซลูชันที่แนะนำด้านล่างนี้ในการใช้งาน แต่วิธีนี้ทำได้: stackoverflow.com/questions/4498649/…
17 จาก 26

คำตอบ:


157

ToolTips ใน WPF สามารถมีอะไรก็ได้ไม่ใช่แค่ข้อความดังนั้นจึงมีคุณสมบัติ ContentStringFormat สำหรับเวลาที่คุณต้องการเพียงแค่ข้อความ คุณจะต้องใช้ไวยากรณ์ขยายเท่าที่ฉันรู้:

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

ฉันไม่แน่ใจ 100% เกี่ยวกับความถูกต้องของการเชื่อมโยงโดยใช้ไวยากรณ์ ElementName จากคุณสมบัติที่ซ้อนกันแบบนั้น แต่คุณสมบัติ ContentStringFormat คือสิ่งที่คุณกำลังมองหา


1
ฉันเห็นฉันคิดว่า ToolTip เป็นเพียงสตริงธรรมดาเช่นเดียวกับใน Windows Forms และใช่ไวยากรณ์ของ ElementName ในกรณีนี้ไม่สามารถเข้าถึงองค์ประกอบภายนอกได้
huseyint

9
โปรดทราบว่า {} จำเป็นต้องใช้เฉพาะเมื่อคุณวาง {0} ไว้ที่จุดเริ่มต้นของสตริงดังนั้นคุณต้องใช้เพื่อแยกความแตกต่างจากมาร์กอัป xaml อื่น ๆ
Shimmy Weitzhandler

5
ใจ = ปลิว. ฉันกดแค่นี้แล้วก็เหมือนว่า "วะ?"

2
มันทำให้ฉันรู้สึกแย่จริงๆว่ารูปแบบสตริงไม่ได้ 'ทำงาน' เมื่อไม่มีการระบุตัวแปลง ฉันต้องเขียน stringformatConverter ของตัวเอง MS ทิ้งบอลอีกแล้ว ...
Gusdor

3
StringFormatจะใช้ได้เฉพาะเมื่อTargetTypeเป็นประเภทของสตริง เนื้อหาเป็นประเภทToolTip object
Johannes Wanzek

22

อาจเป็นข้อบกพร่อง เมื่อคุณใช้ไวยากรณ์สั้น ๆ สำหรับคำแนะนำเครื่องมือ:

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

StringFormat ถูกละเว้น แต่เมื่อคุณใช้ไวยากรณ์แบบขยาย:

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

มันทำงานได้ตามที่คาดไว้


คำตอบที่ถูกต้องที่สุด .. ขอบคุณ!
Amir Mahdi Nassiri

5

ดังที่ Matt กล่าวว่า ToolTip อาจมีอะไรอยู่ข้างในดังนั้นคุณสามารถผูก TextBox ได้ข้อความภายใน ToolTip ของคุณ

<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>

แม้กระทั่งคุณสามารถซ้อนเส้นตารางภายในคำแนะนำเครื่องมือและจัดวางข้อความของคุณได้หากต้องการ


3

รหัสของคุณสามารถสั้นได้ดังนี้:

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

เราจะใช้ข้อเท็จจริงที่ว่า Converters จะไม่ถูกละเลยซึ่งแตกต่างจาก StringFormat

ใส่สิ่งนี้ลงใน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();
        }
    }
}

ใส่สิ่งนี้ลงในResourceDictionary.xamlของคุณ:

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

ในขณะที่ฉันต้องการคำตอบอันดับต้น ๆ ปัญหา ElementBinding ทำให้ฉันสะดุด คำตอบนี้ใช้ได้กับกรณีของฉันโดยที่คนอื่นไม่ทำ
Reginald Blue

0

ในสถานการณ์นี้คุณสามารถใช้การเชื่อมโยงแบบสัมพัทธ์:

<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

ต่อไปนี้เป็นวิธีแก้ปัญหาที่ซับซ้อน แต่ได้ผล

<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>

ฉันต้องการไวยากรณ์ที่ง่ายกว่านี้มากกว่าหนึ่งในคำถามเดิมของฉัน


1
@Shimmy: "ดีกว่า" อยู่ในสายตาของผู้มองและมันก็โอเคที่จะทำเครื่องหมายคำถามของคุณเองเป็นคำตอบที่ยอมรับ
Andomar

1
@Shimmy ยิ่งแย่ไปกว่านั้นคำตอบของเขารวมถึงเรื่องตลก '42' ด้วย

6
@ Andomar ที่ดีกว่าคือสิ่งที่ผู้คนตัดสินใจด้วยคะแนนเสียงของพวกเขายังมีส่วนร่วมที่นี่มันเกือบจะเป็นคำตอบเดียวกัน การทำให้ ppl ตอบคำถามของคุณจากนั้นคัดลอกคำตอบของพวกเขาและได้รับชื่อเสียงเพราะมันเป็นทัศนคติที่ผิดอย่างสิ้นเชิง
Shimmy Weitzhandler
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.