2017-09-04 60 views
0

我有一個StackPanel,一些擴展器,一些文本框和一些按鈕。從按鈕位於同一控件中的控件獲取值

例如,我有以下結構:

StackPanel 
    Expander 1 
    TextBox 1 
    Button 1 
    Expander 2 
    TextBox 2 
    Button 2 
    Expander 3 
    TextBox 3 
    Button 3 

我怎樣才能從那裏擴展按鈕被點擊的textbox.Text?

例如,我單擊按鈕2,我想要在擴展器2中獲得TextBox 2. 所有控件都是以編程方式添加的,而不是StackPanel。

有事嗎?我不知道在相同的擴展器中單擊按鈕時獲取文本框的方式。

我想要2個方法來保存我的擴展頭和它的內容(例如文本框的值)。

第一種方法是右鍵單擊擴展器的標題,它將標題轉換爲文本框,以便我可以編輯文本。通過點擊ENTER,它將把TextBox.Text保存到TextBlock中。哪些工作正常。但是我不能對Button使用相同的代碼。

Expander editable_expander; // Expander sender from Expander_MouseRightButtonDown 

    private void Expander_MouseRightButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     var ex = sender as Expander; 
     TextBox tb = new TextBox(); 
     tb.Text = ex.Header.ToString(); 
     tb.KeyUp += TextBox_KeyUp; 
     ex.Header = tb; 
     editable_expander = ex; 
    } 

    private void TextBox_KeyUp(object sender, KeyEventArgs e) 
    { 
     // Edit Columnname of selected Column when Enter pressed 
     if (e.Key != Key.Enter) return; 

     var tb = sender as TextBox; 
     e.Handled = true; 


     string old_expander_name = editable_expander.Name.ToString(); 
     string old_column_name = old_expander_name.Split('_')[0]; 

     int length = 0; 
     string type = ""; 

     if(OpenConnection() == true) 
     { 
      try 
      { 
       Grid grid = editable_expander.Content as Grid; 
       List<StackPanel> stackpanel = grid.Children.OfType<StackPanel>().ToList(); 
       for(int i = 1; i < 2; i++) 
       { 
        StackPanel sp = stackpanel[i]; 
        List<TextBox> textbox = sp.Children.OfType<TextBox>().ToList(); 
        for(int j = 0; j < textbox.Count; j++) 
        { 
         TextBox tb1 = textbox[j]; 
         length = Convert.ToInt32(tb1.Text); 
        } 
        List<ComboBox> combobox = sp.Children.OfType<ComboBox>().ToList(); 
        for(int k = 0; k < combobox.Count; k++) 
        { 
         ComboBox cb = combobox[k]; 
         type = cb.Text; 
        } 
       } 

       string query = "ALTER TABLE " + editable_expander.Tag + " CHANGE " + old_column_name + " " + tb.Text + " " + type + "(" + length + ")"; 
       MySqlCommand cmd = new MySqlCommand(query, connection); 
       cmd.ExecuteNonQuery(); 
      } 
      catch (MySqlException ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
     } 
     editable_expander.Header = tb.Text; 
    } 
+0

我想要2種方法來保存。 1是右鍵單擊擴展器標題,這會將標題轉換爲文本框。當輸入被按下時,它將會保存並且會改回到TextBlock。我將在我的主題中添加此方法。但我想我不能再次使用按鈕單擊事件,因爲即時通訊工作與文本框事件 –

+0

谷歌有些東西...像「WPF得到父母控制」和「WPF得到特定的孩子控制」 – musefan

+0

我想你想看看爲每個擴展器信息製作一個視圖模型。這樣,該對象可以更新Expander – kenny

回答

1

在MVVM做到這一點的方法:

的XAML風格:

<ItemsControl ItemsSource="{Binding List}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel IsItemsHost="True"/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Expander Header="{Binding SomeText}" MinWidth="100"> 
       <StackPanel Orientation="Horizontal"> 
        <TextBox Text="{Binding SomeText}" MinWidth="100"/> 
        <Button MaxWidth="150" Content="ClickMeToGetYourText" Command="{Binding DataContext.ButtonClickedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ItemsControl}}" CommandParameter="{Binding}"/> 
       </StackPanel> 
      </Expander> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

什麼,你現在看到的是:控件清單:控件放置在StackPanel,每個控制有:Expander SomeText作爲標題,然後在其中,也有TextBox與相同的文本,並按鈕,你可以點擊。 Button有命令,其中你會得到你的文本。

現在一些代碼在C#:

視圖模型:

public class ViewModel 
{ 
    public ObservableCollection<ExpanderData> List { set; get; } = new ObservableCollection<ExpanderData>(); 
    private ICommand _buttonClickedCommand; 
    public ICommand ButtonClickedCommand 
    { 
     get 
     { 
      if (_buttonClickedCommand == null) 
      { 
       _buttonClickedCommand = new RelayCommand(p => ButtonClicked(p)); 
      } 
      return _buttonClickedCommand; 
     } 
    } 

    public void ButtonClicked(Object o) 
    { 
     var expanderData = (ExpanderData)o; 
     var textThatYouWantedToHaveOnButtonClicked = expanderData.SomeText; 
    } 
} 

你這裏有名單,從中您將創建擴展。 Command這將允許你在ButtonClicked上做些什麼,以及將在ButtonClicked事件上觸發的方法。

現在,怎麼看起來ExpanderData類:

public class ExpanderData : INotifyPropertyChanged 
{ 
    private string _someText; 

    public string SomeText 
    { 
     set 
     { 
      _someText = value; 
      OnPropertyChanged(); 
     } 
     get 
     { 
      return _someText; 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    protected void OnPropertyChanged([CallerMemberName]string name = null) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
} 
Here you have your Text that is assign to each of your Expander/TextBox, and event that will fire if you want to update your text from code behind. 

而且RelayCommand實現,它可以讓你綁定命令

public class RelayCommand : ICommand 
{ 
    private Predicate<object> _canExecute; 
    private Action<object> _execute; 

    public RelayCommand(Action<object> execute) 
    { 
     this._canExecute = p => true; 
     this._execute = execute; 
    } 
    public RelayCommand(Predicate<object> canExecute, Action<object> execute) 
    { 
     this._canExecute = canExecute; 
     this._execute = execute; 
    } 

    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 

    public bool CanExecute(object parameter) 
    { 
     return _canExecute(parameter); 
    } 

    public void Execute(object parameter) 
    { 
     _execute(parameter); 
    } 
} 

這就是你如何添加虛擬機到您的視圖:

var vm = new ViewModel(); 
vm.List.Add(new ExpanderData() { SomeText = "Text1" }); 
vm.List.Add(new ExpanderData() { SomeText = "Text2" }); 
vm.List.Add(new ExpanderData() { SomeText = "Text3" }); 
vm.List.Add(new ExpanderData() { SomeText = "Text4" }); 

this.DataContext = vm; 

或者,如果你還想要一些骯髒的方式:

private void ButtonClicked(Object sender, ...) 
{ 
    var yourTextBox = ((Panel)((Button)sender).Parent).Children.OfType<TextBox>().First(); 
    var yourText = yourTextBox.Text; 
} 
相關問題