在按钮所在的控件中获取控件的值

时间:2017-09-04 14:42:43

标签: c# wpf

我有一个StackPanel,一些Expanders,一些文本框和一些按钮。

例如,我有以下结构:

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

如何从点击按钮的Expander中获取textbox.Text?

例如,我单击按钮2,我想在Expander 2中获取TextBox 2。 所有控件都是以编程方式添加的,而不是StackPanel。

有什么类似事件吗?在同一个扩展器中单击按钮时,我不知道获取文本框的方法。

我想要两种方法来保存我的Expander Header及其内容(例如文本框值)。

第一种方法是右键单击Expander的Header,它将Header转换为TextBox,这样我就可以编辑文本了。通过单击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;
    }

1 个答案:

答案 0 :(得分: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作为标题,然后在其中,还有{{ 1}}具有相同的文本和按钮,您可以单击。 TextBox有命令,你可以在其中获取文字。

现在C#中的一些代码:

ViewModel:

Button

您有此列表,您可以从中创建扩展器。 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事件中触发的方法。

现在,看看ExpanderData类:

ButtonClicked

和RelayCommand实现,它允许您绑定命令

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. 

这就是您可以在视图中添加VM的方法:

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;