簡體   English   中英

獲取控件的標簽值

[英]Getting the Tag value of a Control

基於此XAML

<ListView>
    <ListView.View>
        <GridView>
            <GridViewColumn>
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal"
                                    VerticalAlignment="Center"
                                    HorizontalAlignment="Center">
                            <TextBlock Text="{Binding ProductDescription}"/>
                         </StackPanel>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn>
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal"
                                    VerticalAlignment="Center"
                                    HorizontalAlignment="Center">
                            <TextBox x:Name"txtExchange"
                                     Tag="{Binding ProductBarcode}"/>
                            <Button Content="Add"
                                    Tag="{Binding ProductBarcode}"
                                    Click="SelectExchangeProduct" />
                         </StackPanel>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

因為插入的所有行都將具有相同的TextBox ,所以不可能使用x:Name來獲取值。

我將綁定添加到Tag屬性,以便區分所有TextBox 問題是如何找到特定的TextBox 我嘗試使用FindName() ,但是我不知道如何獲取具有特定Tag值的TextBox

我也試過這個:

var txtExchangeQuantity = someParentControl.Children.OfType<TextBox>().Where(x => x.Tag.ToString() == barcode).FirstOrDefault();

但也沒有用 我看到了“ Where部分的潛力,但不知道如何實現它。

這是Click事件:

private void SelectExchangeProduct(object sender, RoutedEventArgs e)
    {
        Button btn = sender as Button;
        string barcode = btn.Tag.ToString();
        var txtExchangeQuantity = grdExchange.Children.OfType<TextBox>().Where(x => x.Tag.ToString() == barcode).FirstOrDefault();

    }

這是我綁定到的對象(使用ObservableCollection

class TransactionList{
    private string _productBarcode;
    public string ProductBarcode
    {
        get { return _productBarcode; }
        set { _productBarcode = value; }
    }
    private string _productDescription;
    public string ProductDescription
    {
        get { return _productDescription; }
        set { _productDescription = value; }
    }
}

在代碼中的某處創建ICommand的實現,如下所示:

public class RelayCommand : ICommand
{
    #region Fields
    private Action<object> execute;
    private Predicate<object> canExecute;
    #endregion

    #region Events
    public event EventHandler CanExecuteChanged;
    #endregion

    #region Constructors
    public RelayCommand(Action<object> execute, Predicate<object> canExecute)
    {
        this.execute = execute ?? throw new ArgumentException(nameof(execute));
        this.canExecute = canExecute ?? throw new ArgumentException(nameof(canExecute));
    }
    #endregion

    #region Methods
    public void InvokeExecuteChanged()
    {
        CanExecuteChanged?.Invoke(this, EventArgs.Empty);
    }
    public bool CanExecute(object parameter)
    {
        return canExecute(parameter);
    }
    public void Execute(object parameter)
    {
        execute(parameter);
    }
    #endregion
}

然后,您可以在視圖模型中實現一個屬性,例如

public RelayCommand SelectExchangeProductCommand { get; private set; }

public ViewModel()
{
    SelectExchangeProductCommand = new RelayCommand(SelectExchangeProductExecute, SelectExchangeProductCanExecute);
}

然后實現兩種方法:

public void SelectExchangeProductExecute(object parameter)
{
    // parameter will then be your Barcode
    if(parameter is string barcode)
    {
         // Now you have the barcode available... but you can really bind anything to end up here.
    }
}

public bool SelectExchangeProductCanExeucte(object parameter)
{
     // return true and false accordingly to execution logic. By default, just return true...
    return true;
}

然后,您可以將Button綁定到xaml中的此命令,如下所示:

<DataTemplate>
    <StackPanel Orientation="Horizontal"
            VerticalAlignment="Center"
            HorizontalAlignment="Center">
       <TextBox x:Name"txtExchange" />
       <Button Content="Add" 
               Command="{Binding Source=ViewModel, Path=SelectExchangeProductCommand}" 
               CommandParameter="{Binding ProductBarcode}" />
   </StackPanel>
</DataTemplate>

像這樣,您不需要標識ButtonTextBox ,只需將各自的數據綁定到CommandParameter ,其余的將由模板完成。

似乎ICommand是要走的路,但這對我來說是個新概念,所以我將告訴您在您的情況下我該怎么做:

將用戶控件中的控件分組為“ ExchangeControl”,例如。 一個文本框“ txtExchange”,一個按鈕“ btnAdd”和一個事件,因此,當您單擊btnAdd時,您將完全控制使用txtExange進行操作。

在需要時實例化它:

someStackPanel.Children.Add(new ExchangeControl() {Content = "SOME TEXT"});

為了使上面的代碼起作用,您應該在ExchangeControl類中具有以下屬性:

private string content;
public string Content
{
    get { return content; }
    set { content = value; txtExchange.Text = value; }
}

所以...現在,如果您創建了按鈕的事件,請單擊btnAdd,以獲取txtExchange內容(某些文本),然后單擊ExchangeControl類

僅作圖,這是一個向按鈕添加事件的示例,假設已經有一個包含某些ExchangeControl項的StackPanel

someStackPanel.Children.Cast<ExangeControl>().ToList().ForEach(ec =>
    ec.btnAdd.Click += (se, a) => MessageBox.Show(ec.txtExchange.Text));

順便說一下,這是如何在選中時獲取DataGrid中特定TextBox的內容:

string someContent = (yourDataGrid.SelectedItem as TextBox).Text;

通過使用VisualTreeHelper來按類型獲取Children會更容易。

如何按類型獲取WPF容器的子代?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM