2011-05-09 63 views
3

我有一個要求,允許選擇在只讀屏幕顯示的文字。格式問題試圖創建一個WPF標籤模板,讓文本選擇

我們開發一個簡單的解決一個想出了使用TextBox而不是標籤或TextBlock的,具有以下樣式:

<Style x:Key="ControlData" TargetType="{x:Type TextBox}"> 
    <Setter Property="Background" Value="Transparent" /> 
    <Setter Property="BorderThickness" Value="0" /> 
    <Setter Property="IsReadOnly" Value="True" /> 
    <Setter Property="TextWrapping" Value="Wrap" /> 
    <!-- unrelated properties ommitted --> 
</Style> 

我不喜歡使用一個TextBox存在的想法,除其他事項外,因爲它迫使我使用Binding Mode=OneWay爲只讀屬性,所以我試圖定義我可以申請到標籤的樣式,以獲得相同的結果:

<Style x:Key="SelectableLabel" TargetType="Label"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="Label"> 
       <TextBox Style="{StaticResource ControlData}" 
         Text="{Binding Path=Content, Mode=OneWay, 
           RelativeSource={RelativeSource FindAncestor, 
               AncestorType=Label}}"/> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

的問題是,一些我的綁定有StringFormat集,那就是迷路了。

  • 有沒有辦法保持外部綁定的格式?
  • 我應該創建我的模板/裝訂不同?
  • 有一個完全不同的做法,是比這更好的?
  • 我應該停止與挑剔和與文本框去?
+0

@wangburger:你是什麼意思? – 2011-05-09 15:59:51

+0

使用「TextBox」有什麼問題?你到目前爲止所說的只是你不喜歡它。爲什麼? – 2011-05-09 16:23:34

+0

@RobertRossney:因爲TextBox是一個**輸入**元素,爲其設置了基礎結構,而不是用於只讀顯示。這也迫使我添加'Mode = OneWay'到我的所有綁定中,而無需setter。 – 2011-05-09 16:38:26

回答

2

我認爲使用標籤並覆蓋控件模板是個不錯的主意。最後,這是WPF中控制邏輯和佈局的分離,您應該利用它來獲得更清晰,更容易理解的xaml代碼。

你有沒有嘗試使用正常綁定的TemplateBinding instad?我不確定這是否會保留外部綁定,但是它是DataTemplates中使用的推薦綁定。

你也應該看看的ContentPresenter類的,雖然我不知道這是否適用在這裏,因爲你內心的文本框中只有一個字符串類型的Text屬性...

編輯: 我解決了這個問題,雖然它是更爲複雜的話,我以爲......

創建樣式如下:

<Application.Resources> 
    <LabelTest:ContentToTextConverter x:Key="contentConverter" /> 
    <Style TargetType="Label"> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="Label"> 
        <TextBox DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource FindAncestor,AncestorType=Label}}"> 
         <TextBox.Text> 
          <MultiBinding Converter="{StaticResource contentConverter}" > 
           <Binding Mode="OneWay" Path="ContentStringFormat" /> 
           <Binding Mode="OneWay" Path="Content" /> 
          </MultiBinding> 
         </TextBox.Text> 
        </TextBox> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Application.Resources> 

的ContentToTextConverter被定義爲以下內容:如何使用

public class ContentToTextConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     var format = values[0] as string; 

     if (string.IsNullOrEmpty(format)) format = "{0}"; 
     else if(format.IndexOf('{') < 0) format = "{0:" + format + "}"; 

     return string.Format(culture, format, values[1]); 
    } 

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

例子:

<Label ContentStringFormat="{}{0}$"> 
    <System:Int64>15</System:Int64> 
</Label> 

這將是很好找到比這一個更好的解決方案,但目前預期它應該工作。

+0

我嘗試了{TemplateBinding內容}沒有結果(文本是空的)和ContentPresenter (同上) – 2011-05-10 11:06:28

+0

這看起來不錯。我會試一試並接受它是否有效。 – 2011-05-13 14:22:56

2

我應該停止與挑剔和與文本框去?

當然。

+0

這是有點我最後的選擇,但我會這樣做,如果它是唯一的方法:-) – 2011-05-09 16:00:44