2015-09-26 28 views
-2

我是WPF的新手,嘗試從winforms移動,所以這是基本問題,但我試圖從按鈕單擊添加到字符串。該場景基本上是一個鍵盤按鈕(0 - 9),用戶按下這些鍵以輸入代碼作爲一種PIN。這樣做的方法是不可談判的,所以我不能用文本框替換並讓用戶鍵入它。我對綁定有一點了解,但是它看起來像是一個字符串的附加字符串,顯然,所有按鈕(0-9)都需要能夠按順序附加到該字符串。所以無論如何,我有一個名爲'EnteredCode'的屬性的ViewModel,並且按鈕位於名爲'buttonsGrid'的網格中。我是否認爲我在網格級別處理ButtonBase.Click事件是正確的,確定哪一個被點擊,然後附加到字符串?附加到字符串顯然是我需要幫助的問題,但正如一般反饋最佳實踐一樣!添加到按鈕上的字符串單擊WPF c#

代碼示例也是一個巨大的幫助。

TIA

+0

你提到視圖模型。你想要做MVVM嗎?如果是這樣你不會使用Button.Click事件。 – KornMuffin

回答

1

所以,你可以把WPF就像Windows窗體和代碼隱藏MainWindow.xaml.cs 實例解決這個問題:

DemonstrationViewModel demoViewModel; 
    public MainWindow() 
    { 
     InitializeComponent(); 
     demoViewModel = new DemonstrationViewModel(); 
     DataContext = demoViewModel; 
    } 

    private void alsoDemoButton_Click(object sender, RoutedEventArgs e) 
    { 
     demoViewModel.EnteredCode += "Clicked"; 
    } 

然而,與視圖模型的在聲明中提,您可能會遵循MVVM模式,並且不推薦在後面的代碼中編寫代碼。

如果您關注的是MVVM模式,那麼ICommands將是一種可行的方法。

僞十歲上下的例子

XAML

<Button x:Name="demoButton" Command="{Binding InsertCommand}"/> 

視圖模型

#region Constructor 
    public DemonstrationViewModel() 
    { 
     InsertCommand = new RelayCommand(ExecuteInsert, CanExecuteInsert); 
    } 
    #endregion 

    private void ExecuteInsert() 
    { 
     EnteredCode += "Clicked! "; 
    } 

Further reading on ICommand in MVVM

+0

一個更簡單的例子,上面的和進一步的閱讀有助於解決問題!謝謝! –

0

你必須努力PasswordBox的密碼屬性綁定到你的ViewModel財產。密碼屬性不可綁定,因爲它不是一個DependencyProperty。這是出於安全原因。

但是,如果您想使其可綁定,則必須使用自定義的AttachedProperty。現在,您正試圖通過按ATM機器上的按鈕來輸入PIN碼,並希望您的密碼也可以被綁定。看到下面的示例,讓你開始。

XAML代碼:

<Window x:Class="WpfEvents._32802407.Win32802407" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:pwd="clr-namespace:PasswordExtras" 
     Title="Win32802407" Height="354.136" Width="385.714"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="143*"/> 
      <ColumnDefinition Width="46*"/> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="16*"/> 
      <RowDefinition Height="19*"/> 
      <RowDefinition Height="32*"/> 
      <RowDefinition Height="95*"/> 
     </Grid.RowDefinitions> 
     <TextBlock TextWrapping="Wrap" Text="Welcome Joshua !" FontSize="18" VerticalAlignment="Center" Margin="10,4,0,4"/> 
     <PasswordBox x:Name="pbPin" pwd:PasswordBoxAssistant.BindPassword="True" pwd:PasswordBoxAssistant.BoundPassword="{Binding Path=PIN, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Grid.Row="2" VerticalAlignment="Center" Width="120" FontSize="18" BorderThickness="0"/> 
     <StackPanel Grid.Column="1" HorizontalAlignment="Left" Height="170" Margin="10,10,0,0" Grid.Row="3" VerticalAlignment="Top" Width="72"> 
      <Button Content="Done" Margin="0,15,0,0" Height="31"/> 
      <Button Content="Clear" Margin="0,15,0,0" Height="31"/> 
      <Button Content="Cancel" Margin="0,15,0,0" Height="31"/> 
     </StackPanel> 
     <WrapPanel ButtonBase.Click="NumericButtons_Click" HorizontalAlignment="Left" Height="147" Margin="10,23,0,0" Grid.Row="3" VerticalAlignment="Top" Width="266"> 
      <Button Content="1" Width="75" Margin="5" Height="25"/> 
      <Button Content="2" Width="75" Margin="5" Height="25"/> 
      <Button Content="3" Width="75" Margin="5" Height="25"/> 
      <Button Content="4" Width="75" Margin="5" Height="25"/> 
      <Button Content="5" Width="75" Margin="5" Height="25"/> 
      <Button Content="6" Width="75" Margin="5" Height="25"/> 
      <Button Content="7" Width="75" Margin="5" Height="25"/> 
      <Button Content="8" Width="75" Margin="5" Height="25"/> 
      <Button Content="9" Width="75" Margin="5" Height="25"/> 
      <Button Content="0" Width="75" Margin="5" Height="25"/> 
     </WrapPanel> 
     <TextBlock HorizontalAlignment="Left" Margin="23,9,0,0" Grid.Row="1" TextWrapping="Wrap" Text="Enter your pin or press cancel" VerticalAlignment="Top"/>  
    </Grid> 
</Window> 

XAML代碼隱藏:

using System; 
using System.Windows; 
using System.Windows.Controls; 

using System.Diagnostics; 

namespace WpfEvents._32802407 
{ 
    /// <summary> 
    /// Interaction logic for Win32802407.xaml 
    /// </summary> 
    public partial class Win32802407 : Window 
    { 
     ViewModelATM atm = new ViewModelATM(); 
     public Win32802407() 
     { 
      InitializeComponent(); 
      this.DataContext = atm; 
     } 

     private void NumericButtons_Click(object sender, RoutedEventArgs e) 
     { 
      string pwd = PasswordExtras.PasswordBoxAssistant.GetBoundPassword(pbPin); 

      if (pwd.Length == 4) 
      { 
       e.Handled = true; 
       return; 
      } 

      pwd = pwd + ((Button)e.OriginalSource).Content; 

      PasswordExtras.PasswordBoxAssistant.SetBoundPassword(pbPin, pwd); 

      Debug.WriteLine(pwd + " : " + atm.PIN); 
     } 
    } 
} 

namespace PasswordExtras 
{ 
    public static class PasswordBoxAssistant 
    { 
     public static readonly DependencyProperty BoundPassword = 
      DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(PasswordBoxAssistant), new PropertyMetadata(string.Empty, OnBoundPasswordChanged)); 

     public static readonly DependencyProperty BindPassword = DependencyProperty.RegisterAttached(
      "BindPassword", typeof (bool), typeof (PasswordBoxAssistant), new PropertyMetadata(false, OnBindPasswordChanged)); 

     private static readonly DependencyProperty UpdatingPassword = 
      DependencyProperty.RegisterAttached("UpdatingPassword", typeof(bool), typeof(PasswordBoxAssistant), new PropertyMetadata(false)); 

     private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      PasswordBox box = d as PasswordBox; 

      // only handle this event when the property is attached to a PasswordBox 
      // and when the BindPassword attached property has been set to true 
      if (d == null || !GetBindPassword(d)) 
      { 
       return; 
      } 

      // avoid recursive updating by ignoring the box's changed event 
      box.PasswordChanged -= HandlePasswordChanged; 

      string newPassword = (string)e.NewValue; 

      if (!GetUpdatingPassword(box)) 
      { 
       box.Password = newPassword; 
      } 

      box.PasswordChanged += HandlePasswordChanged; 
     } 

     private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e) 
     { 
      // when the BindPassword attached property is set on a PasswordBox, 
      // start listening to its PasswordChanged event 

      PasswordBox box = dp as PasswordBox; 

      if (box == null) 
      { 
       return; 
      } 

      bool wasBound = (bool)(e.OldValue); 
      bool needToBind = (bool)(e.NewValue); 

      if (wasBound) 
      { 
       box.PasswordChanged -= HandlePasswordChanged; 
      } 

      if (needToBind) 
      { 
       box.PasswordChanged += HandlePasswordChanged; 
      } 
     } 

     private static void HandlePasswordChanged(object sender, RoutedEventArgs e) 
     { 
      PasswordBox box = sender as PasswordBox; 

      // set a flag to indicate that we're updating the password 
      SetUpdatingPassword(box, true); 
      // push the new password into the BoundPassword property 
      SetBoundPassword(box, box.Password); 
      SetUpdatingPassword(box, false); 
     } 

     public static void SetBindPassword(DependencyObject dp, bool value) 
     { 
      dp.SetValue(BindPassword, value); 
     } 

     public static bool GetBindPassword(DependencyObject dp) 
     { 
      return (bool)dp.GetValue(BindPassword); 
     } 

     public static string GetBoundPassword(DependencyObject dp) 
     { 
      return (string)dp.GetValue(BoundPassword); 
     } 

     public static void SetBoundPassword(DependencyObject dp, string value) 
     { 
      dp.SetValue(BoundPassword, value); 
     } 

     private static bool GetUpdatingPassword(DependencyObject dp) 
     { 
      return (bool)dp.GetValue(UpdatingPassword); 
     } 

     private static void SetUpdatingPassword(DependencyObject dp, bool value) 
     { 
      dp.SetValue(UpdatingPassword, value); 
     } 
    } 
} 

視圖模型

using System; 

namespace WpfEvents._32802407 
{ 
    public class ViewModelATM 
    { 
     string _pin = ""; 
     public string PIN { get { return _pin; } set { _pin = value; } } 

    } 
} 
+0

一個非常好的答案,但我認爲這對手頭的任務來說有點矯枉過正,雖然關於附加屬性的示例也有幫助! –

+0

這不是一個矯枉過正的問題,我已經發布了完整的示例解決方案,因爲您要求提供示例代碼。您需要PasswordBox的附加屬性,並且您還需要綁定。你也在你的問題中表示你想處理按鈕點擊。解決方案根據您的要求發佈。 – AnjumSKhan