如何获取ItemsControl DataTemplate的“选定”实例?

时间:2015-06-27 06:50:19

标签: c# xaml data-binding windows-runtime windows-8.1

我创建了一个动态表单,允许用户使用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”按钮。 item,该项应该删除。

enter image description here

从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;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

绑定到按钮的command属性,而不是使用路由事件。如果这样做,您可以使用绑定的RelativeSource属性来查找项目的ItemsControl父级,该父级应该具有包含要删除的项目的列表的DataContext。

将CommandParameter设置为{Binding},以便delete命令知道要从列表中删除哪个项目。

您可以对删除按钮上的命令绑定执行类似的操作:

<Button x:Name="buttonDelete"
        Command="{Binding ElementName="MyItemsControl", Path=DataContext.DeleteItemCommand}"
        CommandParameter="{Binding}"/>