2013-01-10 74 views
1

我正在使用Silverlight C#和XAML處理Windows Phone應用程序。我的頁面包含一個ListBox,用於呈現用戶可以操作的數據綁定對象列表,即添加/重命名/刪除。Silverlight TextBox VisibilityChanged事件

我知道了工作的項目的添加/重命名完成就地,通過交換一個TextBlock爲根據對象的狀態,即文本框(bool IsEditable屬性)和利用參數化的VisibilityConverter來管理相反的可見性狀態。

<UserControl.Resources> 
    <local:VisibilityConverter x:Key="VisibilityConverter" True="Visible" False="Collapsed"/> 
    <local:VisibilityConverter x:Key="InvertedVisibility" True="Collapsed" False="Visible"/> 
</UserControl.Resources> 
... 
<TextBlock Text="{Binding Name}" Visibility="{Binding IsEditable, Converter={StaticResource InvertedVisibility}}" /> 
<TextBox Text="{Binding Name}" Visibility="{Binding IsEditable, Converter={StaticResource VisibilityConverter}}"/> 

的事情是,我也希望,當它變得可見,從而使屏幕上的鍵盤彈出,而無需點擊文本框的用戶的文本框會自動搶焦點。

因爲有定期的TextBox沒有VisibilityChanged事件,我子類文本框到TextBox2中,並加入我自己的:

public class TextBox2 : TextBox 
{ 
    public TextBox2() 
    { 
     DefaultStyleKey = typeof(TextBox); 
    } 

    public static readonly DependencyProperty VisibilityChangedProperty = DependencyProperty.Register(
     "VisibilityChanged", 
     typeof(string), 
     typeof(TextBox2), 
     new PropertyMetadata("Set the VisibilityChanged event handler")); 

    public event VisibilityChangedEventHandler VisibilityChanged; 

    public delegate void VisibilityChangedEventHandler(object sender, EventArgs e); 

    public new Visibility Visibility 
    { 
     get 
     { 
      return base.Visibility; 
     } 
     set 
     { 
      if (base.Visibility != value) 
      { 
       base.Visibility = value; 
       VisibilityChanged(this, new EventArgs()); 
      } 
     } 
    } 
} 

現在我的XAML看起來像這樣:

<TextBlock Text="{Binding Name}" Visibility="{Binding IsEditable, Converter={StaticResource InvertedVisibility}}"/> 
<local:TextBox2 Text="{Binding Name}" Visibility="{Binding IsEditable, Converter={StaticResource VisibilityConverter}}" VisibilityChanged="ListEdit_VisibilityChanged"/> 

且事件處理程序像這個:

void ListEdit_VisibilityChanged(object sender, EventArgs e) 
{ 
    TextBox textBox = (TextBox)sender; 
    if (textBox.Visibility == System.Windows.Visibility.Collapsed) 
     return; 
    textBox.Focus(); 
} 

TextBox2呈現正常,行爲就像一個T extBox在運行時,但我的VisibilityChanged事件處理程序不觸發當數據綁定flipflip的值。

IsEditable定義了可見性,並且TextBox2確實可以正確顯示,所以數據綁定正在工作。

我可以通過獲取TextBox2實例並在代碼中設置可見性來以編程方式觸發事件。這也是有效的。

但是這個負責設置可見性的數據綁定方案似乎不起作用。

任何想法爲什麼不呢?

回答

0

這是怎麼了我的TextBox2中類現在看起來:

public class TextBox2 : TextBox 
{ 
    public event VisibilityChangedEventHandler VisibilityChanged; 
    public delegate void VisibilityChangedEventHandler(object sender, EventArgs e); 
    public static readonly DependencyProperty VisibilityChangedProperty = DependencyProperty.Register(
     "VisibilityChanged", typeof(VisibilityChangedEventHandler), typeof(TextBox2), null); 

    static readonly DependencyProperty MirrorVisibilityProperty = DependencyProperty.Register(
     "MirrorVisibility", typeof(Visibility), typeof(TextBox2), new PropertyMetadata(MirrorVisibilityChanged)); 

    public TextBox2() 
    { 
     SetBinding(TextBox2.MirrorVisibilityProperty, new Binding("Visibility") { Source = this }); 
    } 

    static void MirrorVisibilityChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     ((TextBox2)obj).VisibilityChanged(obj, null); // raise event 
    } 
} 
2

以下是我使用的兩種解決方案。

解決方案1不需要子類,但解決方案2更易於重用。

。您可以訂閱Loaded事件TextBox的,並迫使一個焦點,像這樣:

void TextBox_Loaded_Focus(object sender, System.Windows.RoutedEventArgs e) { 
     ForceFocusControl((Control)sender);    
    } 

    void ForceFocusControl(Control control) { 

     control.Focus(); 

     if (FocusManager.GetFocusedElement() != control) { 

      Dispatcher.BeginInvoke(() => ForceFocusControl(control)); 
     } 
    } 

該解決方案進入一個遞歸循環,雖然,你可能要添加一些檢查,使之更安全。

。保持你的子類TextBox2,和而創建,綁定到基類的Visibility財產的私人MyVisibility依賴屬性,而且還指定DependencyProperty_Changed處理器,就像這樣:

/// <summary> 
    /// <see cref="TextBox2"/> will focus itself when it becomes visible. 
    /// </summary> 
    public sealed class TextBox2 : TextBox { 

     public TextBox2() { 

      SetBinding(TextBox2.MyVisibilityProperty, new Binding("Visibility") { Source = this }); 
     } 

     static readonly DependencyProperty MyVisibilityProperty = DependencyProperty.Register(
      /* name = */ "MyVisibilityProperty", 
      /* property type = */ typeof(Visibility), 
      /* owner type = */ typeof(TextBox2), 
      /* meta = */ new PropertyMetadata(MyVisibilityProperty_Changed)); 

     static void MyVisibilityProperty_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e) { 

      TextBox2 TextBox2 = (TextBox2)d; 

      if (TextBox2.Visibility == Visibility.Visible) { 
       TextBox2.Focus(); 
      } 
     } 
    } 
+0

謝謝馬丁!我將_property mirroring_技術與我的外部事件處理程序代碼合併在一起,並且它完美地工作。 – larryk78

+0

不客氣! –