2012-12-24 100 views
1

我可能會接近這一切錯誤,所以告訴我,如果你有其他建議。XAML如何使文本塊/文本框編輯切換?

我正在爲Windows RT開發一個應用程序,它將向用戶顯示一堆文本塊,例如字符統計信息。 用戶將看到:

 
Str: 10 
Con: 10 
Dex: 10 

等。

我希望他們能在填補這些,那麼具有基於結果計算出的選擇視圖值。

我雖然是在頂部點擊「編輯」按鈕,然後在每個可編輯的文本塊切換一些文本框。

當試圖對此進行設置使用「混合爲Visual Studio」我似乎無法讓一個文本框,比49x34小(遠遠超過我的文本塊較大)。

我打算找到一種方法來爲每個文本塊(使用它的尺寸)在按鈕單擊時生成一個文本框,但是由於它們將始終是相同的,並且會有很多它們是我正在嘗試製作的他們通過混合靜態。

我對XAML很新,而且我似乎無法找到像這樣設置可編輯字段的人的一個很好的例子,所以我應該如何讓一堆靜態字段具有可編輯的文本框?

回答

5

我想創建無論是在XAML的TextBox和TextBlock的覆蓋,並直接把他們放在各自的頂部其他在網格中,使用水平和垂直對齊到「中心」以確保文本始終完全排列。我也會使用靜態寬度來確保列很好地排列。

從那裏,你可以直接在能見度綁定到一些布爾「IsEditing」屬性,以確保只有其中一個控件同時顯示。

<StackPanel Orientation="Horizontal"> 
    <TextBlock Text="Str: " Width="40" VerticalAlignment="Center" /> 
    <Grid Width="40" VerticalAlignment="Center"> 
     <TextBlock Text="{Binding Strength}" 
      Visibility="{Binding IsEditing, Converter={StaticResource BooleanToInvisibilityConverter}}" 
      VerticalAlignment="Center" 
      HorizontalAlignment="Center" /> 
     <TextBox Text="{Binding Strength}" 
      Visibility="{Binding IsEditing, Converter={StaticResource BooleanToVisibilityConverter}}" 
      VerticalAlignment="Center" 
      HorizontalContentAlignment="Center" /> 
    </Grid> 
</StackPanel> 

某處沿着你必須確定你的「BooleanToVisibility」和「BooleanToInvisiblity」轉換器資源的方式。我喜歡this implementation by Diedrik Krols。這很好,很簡單,可以選擇倒置。

+0

這看起來正是我所需要的。我只需要設置它。謝謝! – Sambardo

+0

Scratch,我只是在我的項目中設置它,並在應用程序中得到「Windows應用程序項目中不支持BooleanToVisibilityConverter」的語法錯誤。xaml,當我嘗試添加像「」 爲什麼這個XAML如此不同?似乎應該有一個簡單的方法來做到這一點。 – Sambardo

+0

我提到,在答案的最後:您必須實現一個IValueConverter。按照鏈接瞭解示例實現。 – BTownTKD

4

您可能希望爲TextBox使用樣式,該樣式根據「IsReadOnly」屬性是否爲true而發生變化。

當IsReadOnly爲true時,可以將BorderBrush和Background設置爲Transparent,從而使其看起來像普通的文本塊。

這樣,您不必重疊TextBlocks和TextBoxes;只需使用TextBox控件自己,並在單擊「編輯」按鈕時切換「IsReadOnly」屬性。

在你的資源:

<Style x:Key="MyEditableField" TargetType={x:Type TextBox}> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding IsReadOnly, RelativeSource={RelativeSource Self}}" Value="True"> 
      <Setter Property="BorderBrush" Value="Transparent" /> 
      <Setter Property="Background" Value="Transparent" /> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

而且這裏是你編輯的領域之一:

<StackPanel Orientation="Horizontal"> 
    <TextBlock Text="Str: " /> 
    <TextBox Style="{StaticResource MyEditableField}" 
      Text="{Binding Strength}" 
      IsReadOnly="{Binding IsEditingDisabled}" /> 
</StackPanel> 
+0

所以,如果我理解這個權利,該數據觸發意味着,如果我將它設置爲只讀,在BorderBrush和背景將觸發並關閉? – Sambardo

+0

我好像上的TargetType =要得到錯誤{X:TextBox類型}它不喜歡它作爲一個有效的名稱。 和Datatrigger似乎拋出錯誤了。我從根本上誤解了這是如何工作的,還是有一些我需要包括的圖書館? (在網上搜索今天上午沒有顯示) – Sambardo

+0

哦,我的進一步調查中,Windows 8 XAML不再支持Style.Triggers。相反,您現在應該使用VisualStateManager。這個答案需要更多的研究,因爲使用VisualStateManager + Attahced行爲的組合進行手動轉換的聲音爲您的需求有點矯枉過正。我可能會發佈一個全新的答案來幫助您採用以前的方法。 – BTownTKD

4

晚的答案,但誰願意還可以創建自定義可編輯的文本框,它很容易其實這裏是代碼(很明顯,你可以修改它根據自己的需要)

public class EditableTextBox : TextBox 
{ 
    public EditableTextBox() 
    { 
     this.BorderBrush = new SolidColorBrush(Colors.Black); 
    } 
    protected override void OnTapped(TappedRoutedEventArgs e) 
    { 
     this.IsReadOnly = false; 
     SetEditingStyle(); 
     base.OnTapped(e); 
    } 

    protected override void OnDoubleTapped(DoubleTappedRoutedEventArgs e) 
    { 
     this.IsReadOnly = false; 
     SetEditingStyle(); 
     base.OnDoubleTapped(e); 
    } 

    protected override void OnLostFocus(RoutedEventArgs e) 
    { 
     this.IsReadOnly = true; 
     SetReadonlyStyle(); 
     base.OnLostFocus(e); 
    } 

    public void SetReadonlyStyle() 
    { 
     this.BorderBrush.Opacity = 0; 
     this.Background.Opacity = 0; 
    } 

    public void SetEditingStyle() 
    { 
     this.BorderBrush.Opacity = 1; 
     this.Background.Opacity = 1; 
    } 
} 

樣品:

enter image description here

enter image description here

教程:Full tutorial url

+0

鏈接被破壞.. –

0

此建立過BTownTKD的解決方案,但我真的喜歡一個解決方案儘可能在這裏儘可能多的WPF是有點修改的,在我的情況,我想修改標籤控件的名稱。

我的視圖模型具有下面的代碼:

private bool _isEditingName = false; 

    public bool IsEditingName 
    { 
     get 
     { 
      return _isEditingName; 
     } 
     set 
     { 
      _isEditingName = value; 
      OnPropertyChanged(); 
     } 
    } 

    public ICommand StartEditing 
    { 
     get 
     { 
      return new DelegateCommand(() => 
      { 
       IsEditingName = true; 
      }); 
     } 
    } 

    public ICommand EndEditing 
    { 
     get 
     { 
      return new DelegateCommand(() => 
      { 
       IsEditingName = false; 
      }); 
     } 
    } 

接下來是我的觀點是,對標籤(而不是內容只是選項卡)中的數據模板:

<TabControl ItemsSource="{Binding Items}" SelectedItem="{Binding ActiveItem}"> 
    <TabControl.ItemTemplate> 
     <DataTemplate> 
      <Grid VerticalAlignment="Center"> 
       <TextBlock x:Name="TabName" Text="{Binding Name}" Visibility="{Binding IsEditingName, Converter={StaticResource InvertedBoolToVisConverter}}" VerticalAlignment="Center" HorizontalAlignment="Stretch" TextAlignment="Left"> 
        <TextBlock.InputBindings> 
         <MouseBinding MouseAction="LeftDoubleClick" Command="{Binding StartEditing}" /> 
        </TextBlock.InputBindings> 
       </TextBlock> 
       <TextBox Text="{Binding Name}" Visibility="{Binding IsEditingName, Converter={StaticResource BoolToVisConverter}}" VerticalAlignment="Center" HorizontalContentAlignment="Stretch" TextAlignment="Left" IsVisibleChanged="TextBox_IsVisibleChanged"> 
        <i:Interaction.Triggers> 
         <i:EventTrigger EventName="LostFocus"> 
          <i:InvokeCommandAction Command="{Binding EndEditing}" /> 
         </i:EventTrigger> 
        </i:Interaction.Triggers> 
        <TextBox.InputBindings> 
         <KeyBinding Key="Enter" Command="{Binding EndEditing}" /> 
        </TextBox.InputBindings> 
       </TextBox> 
      </Grid>     
     </DataTemplate> 
    </TabControl.ItemTemplate> 
</TabControl> 

最後,但並非最不重要的,我想雙擊把我在編輯模式,並支持自動對焦的文本框,選擇所有即時打字的內容。 XAML中的解決方案中沒有一個是乾淨的後面,所以我最後只是決定加入這對能見度文本框一個簡單的代碼改變處理程序:

private void TextBox_IsVisibleChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e) 
    { 
     var box = sender as TextBox; 
     if (box != null) 
     { 
      if ((bool)e.NewValue) 
      { 
       box.Focus(); 
       box.SelectAll(); 
      } 
     } 
    } 

出所有我找到了解決方案,這是迄今爲止我喜愛。感謝大家爲你的帖子!幫助我找到一個非常好的整體解決方案,以解決我的問題!