[英]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>
像這樣,您不需要標識Button
或TextBox
,只需將各自的數據綁定到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會更容易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.