如何获取 ItemsControl DataTemplate 的 "selected" 实例?
How do I get the "selected" instance of an ItemsControl DataTemplate?
我创建了一个动态表单,允许用户使用 ItemsControl 添加项目的变体。
<ItemsControl x:Name="variationItemsControl"
ItemsSource="{Binding FormItem.Variations}"
Visibility="Collapsed">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width=".60*"/>
<ColumnDefinition Width=".30*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Margin="0,0,1,0">
<TextBlock
Foreground="White"
Text="Variation Name"/>
<TextBox
x:Name="variationName"
Style="{StaticResource FlyoutField}"
Text="{Binding VariationName, Mode=TwoWay}"/>
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock
Foreground="White"
Text="Price"/>
<TextBox
Style="{StaticResource FlyoutField}"
Text="{Binding VariationPrice, Mode=TwoWay}"/>
</StackPanel>
<Button
Grid.Column="2"
Margin="0,0,0,6"
Content="X"
HorizontalAlignment="Stretch"
Click="deleteVariationButton_Click"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
在网格中,有一个按钮,单击该按钮后,我希望删除该模板实例。例如,在下图中,如果我单击 12 盎司的 'X' 按钮。项,应删除该项。
从 ItemsControl 的 ItemsSource 中删除该实例是一件简单的事情,但我需要知道如何在 'X' 按钮单击事件中执行此操作。对象发送者是按钮本身,RoutedEventArgs 似乎没有包含任何我可以使用的相关信息。
private void deleteVariationButton_Click(object sender, RoutedEventArgs e)
{
// what do I do here?
}
有没有办法获取我点击的'X'按钮所在的模板容器的索引?如果我能得到那个索引,那么它就是从 ItemsControl 的 ItemsSource 容器中简单删除。
编辑更多代码:
public class Item : ObservableObject, IEquatable<Item>
{
private string itemName;
public string ItemName
{
get { return itemName; }
set { Set<string>(() => ItemName, ref itemName, value.ToString().Trim()); }
}
private Category itemCategory;
public Category ItemCategory
{
get { return itemCategory; }
set { Set<Category>(() => ItemCategory, ref itemCategory, value); }
}
private decimal? singlePrice;
public decimal? SinglePrice
{
get { return singlePrice; }
set { Set<decimal?>(() => SinglePrice, ref singlePrice, value); }
}
private ObservableCollection<Variation> variations;
public ObservableCollection<Variation> Variations
{
get { return variations; }
set { Set<ObservableCollection<Variation>>(() => Variations, ref variations, value); }
}
private bool hasVariations;
public bool HasVariations
{
get { return hasVariations; }
set { Set<bool>(() => HasVariations, ref hasVariations, value); }
}
public Item()
{
itemCategory = new Category();
Variations = new ObservableCollection<Variation>();
}
public Item(Item other)
{
Copy(other);
}
public void Copy(Item other)
{
if (this != other)
{
ItemName = other.ItemName;
ItemCategory = new Category();
ItemCategory.CategoryName = other.ItemCategory.CategoryName;
ItemCategory.CategoryColor = other.ItemCategory.CategoryColor;
SinglePrice = other.SinglePrice;
Variations = new ObservableCollection<Variation>();
foreach (Variation v in other.variations)
{
variations.Add(new Variation(v));
}
}
}
public bool Equals(Item other)
{
if (variations.Count() != other.variations.Count())
return false;
for (int i = 0; i < variations.Count(); i++)
{
if (!variations.ElementAt(i).Equals(other.variations.ElementAt(i)))
return false;
}
if (itemName == other.itemName &&
itemCategory.CategoryName == other.itemCategory.CategoryName &&
itemCategory.CategoryColor == other.itemCategory.CategoryColor &&
singlePrice == other.singlePrice &&
hasVariations == other.hasVariations)
return true;
return false;
}
public class Variation : ObservableObject
{
public RelayCommand DeleteVariationCommand { get; private set; }
private string variationName;
public string VariationName
{
get { return variationName; }
set { Set<string>(() => VariationName, ref variationName, value.ToString().Trim()); }
}
private decimal? variationPrice;
public decimal? VariationPrice
{
get { return variationPrice; }
set { Set<decimal?>(() => VariationPrice, ref variationPrice, value); }
}
public Variation()
{
variationName = "";
variationPrice = 0M;
DeleteVariationCommand = new RelayCommand(
() => DeleteVariation(),
() => CanDeleteVariation());
}
public void DeleteVariation()
{
}
public bool CanDeleteVariation()
{
return true;
}
public Variation(Variation other)
{
variationName = other.variationName;
variationPrice = other.variationPrice;
}
public bool Equals(Variation other)
{
if (variationName.Equals(other.variationName) && variationPrice == other.variationPrice)
return true;
return false;
}
}
}
绑定到按钮的命令 属性,而不是使用路由事件。如果这样做,您可以使用绑定的 RelativeSource 属性 来查找项目的 ItemsControl 父级,它应该具有包含要删除的项目的列表的 DataContext。
将 CommandParameter 设置为 {Binding} 以便删除命令知道要从列表中删除哪个项目。
您可以为删除按钮上的命令绑定执行类似的操作:
<Button x:Name="buttonDelete"
Command="{Binding ElementName="MyItemsControl", Path=DataContext.DeleteItemCommand}"
CommandParameter="{Binding}"/>
我创建了一个动态表单,允许用户使用 ItemsControl 添加项目的变体。
<ItemsControl x:Name="variationItemsControl"
ItemsSource="{Binding FormItem.Variations}"
Visibility="Collapsed">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width=".60*"/>
<ColumnDefinition Width=".30*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Margin="0,0,1,0">
<TextBlock
Foreground="White"
Text="Variation Name"/>
<TextBox
x:Name="variationName"
Style="{StaticResource FlyoutField}"
Text="{Binding VariationName, Mode=TwoWay}"/>
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock
Foreground="White"
Text="Price"/>
<TextBox
Style="{StaticResource FlyoutField}"
Text="{Binding VariationPrice, Mode=TwoWay}"/>
</StackPanel>
<Button
Grid.Column="2"
Margin="0,0,0,6"
Content="X"
HorizontalAlignment="Stretch"
Click="deleteVariationButton_Click"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
在网格中,有一个按钮,单击该按钮后,我希望删除该模板实例。例如,在下图中,如果我单击 12 盎司的 'X' 按钮。项,应删除该项。
从 ItemsControl 的 ItemsSource 中删除该实例是一件简单的事情,但我需要知道如何在 'X' 按钮单击事件中执行此操作。对象发送者是按钮本身,RoutedEventArgs 似乎没有包含任何我可以使用的相关信息。
private void deleteVariationButton_Click(object sender, RoutedEventArgs e)
{
// what do I do here?
}
有没有办法获取我点击的'X'按钮所在的模板容器的索引?如果我能得到那个索引,那么它就是从 ItemsControl 的 ItemsSource 容器中简单删除。
编辑更多代码:
public class Item : ObservableObject, IEquatable<Item>
{
private string itemName;
public string ItemName
{
get { return itemName; }
set { Set<string>(() => ItemName, ref itemName, value.ToString().Trim()); }
}
private Category itemCategory;
public Category ItemCategory
{
get { return itemCategory; }
set { Set<Category>(() => ItemCategory, ref itemCategory, value); }
}
private decimal? singlePrice;
public decimal? SinglePrice
{
get { return singlePrice; }
set { Set<decimal?>(() => SinglePrice, ref singlePrice, value); }
}
private ObservableCollection<Variation> variations;
public ObservableCollection<Variation> Variations
{
get { return variations; }
set { Set<ObservableCollection<Variation>>(() => Variations, ref variations, value); }
}
private bool hasVariations;
public bool HasVariations
{
get { return hasVariations; }
set { Set<bool>(() => HasVariations, ref hasVariations, value); }
}
public Item()
{
itemCategory = new Category();
Variations = new ObservableCollection<Variation>();
}
public Item(Item other)
{
Copy(other);
}
public void Copy(Item other)
{
if (this != other)
{
ItemName = other.ItemName;
ItemCategory = new Category();
ItemCategory.CategoryName = other.ItemCategory.CategoryName;
ItemCategory.CategoryColor = other.ItemCategory.CategoryColor;
SinglePrice = other.SinglePrice;
Variations = new ObservableCollection<Variation>();
foreach (Variation v in other.variations)
{
variations.Add(new Variation(v));
}
}
}
public bool Equals(Item other)
{
if (variations.Count() != other.variations.Count())
return false;
for (int i = 0; i < variations.Count(); i++)
{
if (!variations.ElementAt(i).Equals(other.variations.ElementAt(i)))
return false;
}
if (itemName == other.itemName &&
itemCategory.CategoryName == other.itemCategory.CategoryName &&
itemCategory.CategoryColor == other.itemCategory.CategoryColor &&
singlePrice == other.singlePrice &&
hasVariations == other.hasVariations)
return true;
return false;
}
public class Variation : ObservableObject
{
public RelayCommand DeleteVariationCommand { get; private set; }
private string variationName;
public string VariationName
{
get { return variationName; }
set { Set<string>(() => VariationName, ref variationName, value.ToString().Trim()); }
}
private decimal? variationPrice;
public decimal? VariationPrice
{
get { return variationPrice; }
set { Set<decimal?>(() => VariationPrice, ref variationPrice, value); }
}
public Variation()
{
variationName = "";
variationPrice = 0M;
DeleteVariationCommand = new RelayCommand(
() => DeleteVariation(),
() => CanDeleteVariation());
}
public void DeleteVariation()
{
}
public bool CanDeleteVariation()
{
return true;
}
public Variation(Variation other)
{
variationName = other.variationName;
variationPrice = other.variationPrice;
}
public bool Equals(Variation other)
{
if (variationName.Equals(other.variationName) && variationPrice == other.variationPrice)
return true;
return false;
}
}
}
绑定到按钮的命令 属性,而不是使用路由事件。如果这样做,您可以使用绑定的 RelativeSource 属性 来查找项目的 ItemsControl 父级,它应该具有包含要删除的项目的列表的 DataContext。
将 CommandParameter 设置为 {Binding} 以便删除命令知道要从列表中删除哪个项目。
您可以为删除按钮上的命令绑定执行类似的操作:
<Button x:Name="buttonDelete"
Command="{Binding ElementName="MyItemsControl", Path=DataContext.DeleteItemCommand}"
CommandParameter="{Binding}"/>