【问题标题】:Failing to retrieve Textbox value when Button is clicked单击按钮时无法检索文本框值
【发布时间】:2012-10-06 06:26:21
【问题描述】:

看标题,它可能看起来很简单,但它有点棘手。我正在开发一个 wpf 应用程序,我需要在其中动态生成按钮、标签和文本框。在我的 VoltageView XAml 文件中,我创建了一个堆栈面板。在我的 VoltageChannelView xaml 文件中,我创建了所有 UI 组件。

我在一定程度上实现了如下:

电压视图:

<Grid Grid.Row="1" Style="{DynamicResource styleBackground}" Name="VoltageChannels" >
        <StackPanel Height="Auto" Name="stackPanel" Width="Auto" MinHeight="300"></StackPanel>
</Grid>

VoltageChannelView:

<Label Grid.Column="0" Content="{Binding ChannelName}" />
<TextBox Grid.Column="1" Text="{Binding VoltageText}" />
<Button Grid.Column="1" Content="Set" CommandParameter="{Binding VoltageText}" Command="{Binding VoltageCommand}" />

我将上述动态生成的 Ui 组件添加到我的 VoltageView.xaml.cs 中的堆栈面板中,如下所示:

VoltageViewModel mVoltageViewModel = new VoltageViewModel();

// Called in constructor
public void OnChildAdd()
    {            
        foreach (VoltageBoardChannel mVoltageChannelViewModel in mVoltageViewModel.VoltageChannelList)
        {
            VoltageChannelView mVoltageChannelView = new VoltageChannelView();
            mVoltageChannelView.Margin = new Thickness(2);
            mVoltageChannelView.ChannelInfo = mVoltageChannelViewModel;
            stackPanel.Children.Add(mVoltageChannelView);
        }
    }

VoltageViewModel 类:

public ObservableCollection<VoltageBoardChannel> channelList = null;

    public ObservableCollection<VoltageBoardChannel> redhookChannels = new ObservableCollection<VoltageBoardChannel>
    {             
         new VoltageBoardChannel { ChannelName = "VDD_IO_AUD", IsAvailable = true},
         new VoltageBoardChannel { ChannelName = "VDD_CODEC_AUD", IsAvailable = true},
         new VoltageBoardChannel { ChannelName = "VDD_DAL_AUD", IsAvailable = true},
         new VoltageBoardChannel { ChannelName = "VDD_DPD_AUD", IsAvailable = true},
         new VoltageBoardChannel { ChannelName = "VDD_PLL_AUD", IsAvailable = true},
         new VoltageBoardChannel { ChannelName = "VDD_AMP1_AUD", IsAvailable = true}             
    };       

    public ObservableCollection<VoltageBoardChannel> bavaria1Channels = new ObservableCollection<VoltageBoardChannel>
    {
         new VoltageBoardChannel { ChannelName = "VDD__MAIN", IsAvailable = true},
         new VoltageBoardChannel { ChannelName = "VDD__IO", IsAvailable = true},
         new VoltageBoardChannel { ChannelName = "VDD__CODEC", IsAvailable = true},
         new VoltageBoardChannel { ChannelName = "VDD__LDO", IsAvailable = true},
         new VoltageBoardChannel { ChannelName = "VDD__AMP", IsAvailable = true},  

    };        

    public VoltageViewModel()
    {
        channelList = new ObservableCollection<VoltageBoardChannel>();
        channelList = bavaria1Channels;          

    }

    public ObservableCollection<VoltageBoardChannel> VoltageChannelList
    {
        get 
        { 
            return channelList; 
        }

        set
        { 
            channelList = value;
            OnPropertyChanged("ChannelList");
        }
    }

    RelayCommand _voltageCommand;
    public ICommand VoltageCommand
    {
        get
        {
            if (_voltageCommand == null)
            {
                _voltageCommand = new RelayCommand(param => this.DoSomethingExecute, param => this.DoSomethingCanExecute);
            }
            return _voltageCommand;
        }
    }

    public bool DoSomethingCanExecute(object param)
    {
        return true;
    }

    public void DoSomethingExecute(object param)
    {

    }

正如您在启动时看到的那样,显示 BAVARIA1 频道。

VoltageBoardChannel(模型)类:

private string mChannelName;
    public string ChannelName
    {
        get
        {
            return mChannelName;
        }
        set
        {
            mChannelName = value;
            OnPropertyChanged("ChannelName");
        }
    }

    private bool mIsAvailable;
    public bool IsAvailable
    {
        get; set;
    }

    string voltageText = string.Empty;
    public string VoltageText
    {
        get
        {
            return voltageText;
        }

        set
        {
            voltageText = value;
            OnPropertyChanged("VoltageText");
        }
    }      

因此,当我运行该应用程序时,它会动态显示 bavaria1 频道 4 次,如列表中维护的那样。现在在每个动态生成的控件上都有一个文本框和按钮。

您可以在VoltageChannelView.xaml 中注意到我已经完成了绑定 bw 按钮和文本框。我想在文本框中输入值并单击 SET 按钮,它应该检索输入的值,以便可以完成进一步的操作。基本上应该有一个 SET 按钮的事件,它应该将 Textbox 中写入的文本作为参数传递。

我怎样才能实现它? :)

【问题讨论】:

  • 你在哪里设置电压命令?
  • @Mark:出现在模型类中:)
  • 是缺少的代码只有 public ICommand VoltageCommand { get;放; } ?
  • @Mark:是的,只有public ICommand VoltageCommand { get; set; }。他们有问题吗?能详细点吗

标签: c# .net wpf binding textbox


【解决方案1】:

当我看到这一点时,您是否错过了您的命令的实施。 您需要的是处理您的命令的逻辑。

复制本文来源WPF Apps With The Model-View-ViewModel Design Pattern

RelayCommand 类

public class RelayCommand : ICommand
{
    #region Fields

    readonly Action<object> _execute;
    readonly Predicate<object> _canExecute;        

    #endregion // Fields

    #region Constructors

    public RelayCommand(Action<object> execute)
    : this(execute, null)
    {
    }

    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");

        _execute = execute;
        _canExecute = canExecute;           
    }
    #endregion // Constructors

    #region ICommand Members

    [DebuggerStepThrough]
    public bool CanExecute(object parameter)
    {
        return _canExecute == null ? true : _canExecute(parameter);
    }

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

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

    #endregion // ICommand Members
}

您的命令实现应该如下所示:

RelayCommand _voltageCommand ;
public ICommand VoltageCommand 
{
    get
    {
        if (_voltageCommand == null)
        {
            _voltageCommand = new RelayCommand(this.DoSomethingExecute,
                this.DoSomethingCanExecute);
        }
        return _voltageCommand;
    }
}

执行方法:

public void DoSomethingExecute(object param)
{
    // param is your string        
    //Do Something with VoltageText
}

CanExecute方法

public bool DoSomethingCanExecute(object param)
{
    return true;        
}

【讨论】:

  • 我从 Model 类中删除了 VoltageCommand 并添加了您在上面编写的代码。它在 this.DoSomethingExecute 和 this.DoSomethingCanExecute 处引发错误 Only assignment, call, increment, decrement, and new object expressions can be used as a statement。另外我将如何获取在文本框中输入的文本?
  • 如果你需要,你还需要一个 DoSomethingCanExecute 方法,我会更新我的答案。您在 DoSomethingExecute(object param) 中获得的来自 VoltageCommand 的文本,该参数是您的文本。
  • 可以做这样的事情吗:new VoltageBoardChannel { ChannelName = "VDD__MAIN", IsAvailable = true, VoltageCommand = m_VoltageCommand} 使用这个 m_voltageCommand,做一个委托命令并给我通过某种方法输入的文本???
  • 是的,我添加了这两种方法,但它仍然在 this.DoSomethingExecute 处引发错误
  • 你的方法看起来像我上面的例子吗?我已经检查了它应该工作的代码。
猜你喜欢
  • 1970-01-01
  • 2020-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多