将按钮属性设置为基于列表项在lisbox中不可见

时间:2018-08-27 16:00:19

标签: c# wpf

我是C#和WPF的新手,仍然在学习绳索。我目前正在尝试使用ListBox在列表中显示一些预定义的项目。我正在使用ObservableCollection来保存这些项目,并将该集合绑定到该ListBox。除了删除它们,我还允许用户将新项目添加到列表或更新选定的项目。对于该列表中的每个项目,我要在其旁边显示一个DELETE按钮。但是,每个按钮仅对用户添加的项目可见,而不对任何预定义的项目可见。

我目前能够为列表中的每个项目显示DELETE按钮。因此,我的问题是,是否可以将列表中每个项目的DELETE按钮的属性设置为仅对新添加到其中的项目可见,而对于预定义(默认)项目不显示DELETE按钮?如果是这样,我将如何去做? (这就是我努力弄清楚的。)

我应该发布我的代码吗?

谢谢

这是具有列表和用于向列表添加新项目的控件的视图模式。

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <ListBox x:Name="DrinksListBox" HorizontalAlignment="Center" Height="325" Width="275" Margin="0,0,0,0" VerticalAlignment="Center" Grid.Column="0">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid Margin="0,2">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Type}" Width="80"  Margin="0,0,10,0" Grid.Column="0"/>
                    <TextBlock Text="{Binding Name}" Width="80"  Margin="0,0,10,0" Grid.Column="1" HorizontalAlignment="Left"/>
                    <Button x:Name="DrinkDeleteButton" Content="Delete" Click="CmdDeleteDrink_Clicked" HorizontalAlignment="Right" Grid.Column="2"/>
                </Grid>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <TextBox x:Name="DrinkNameTextBox" Grid.Column="1" HorizontalAlignment="Left" Height="45" Margin="0,0,0,100" TextWrapping="Wrap" Text="Enter Drink Name" VerticalAlignment="Center" Width="240" FontSize="20" VerticalContentAlignment="Center"/>
    <ComboBox x:Name="DrinkTypeComboBox" Grid.Column="1" HorizontalAlignment="Left" Margin="0,47,0,0" VerticalAlignment="Top" Width="240" Height="45" ItemsSource="{Binding Drinks,  Mode=OneWay}" DisplayMemberPath="Type" FontSize="20"/>
    <Button x:Name="AddDrinkButton" Content="Add Drink" Grid.Column="1" HorizontalAlignment="Right" Margin="0,0,10,100" VerticalAlignment="Center" Width="100" Height="45" Click="CmdAddDrink_Clicked"/>
</Grid>

这是我的代码背后。我有一个酒类属性的内部类,和一个设置要使用的列表的主类。

public partial class MainWindow : Window
{
    public ObservableCollection<Drinks> Drinks { get; private set; }

    public MainWindow()
    {
        InitializeComponent();

        Drinks = new ObservableCollection<Drinks>();

        Drinks.Add(new Drinks("Soda", "Pepsi"));            
        Drinks.Add(new Drinks("Tea", "Lemon"));
        Drinks.Add(new Drinks("Caffinated", "Coffee"));
        Drinks.Add(new Drinks("Other", "Water"));

        DrinksListBox.ItemsSource = Drinks;
        DrinkTypeComboBox.ItemsSource = Drinks;
    }

    private void CmdDeleteDrink_Clicked(object sender, RoutedEventArgs e)
    {
        Button cmd = (Button)sender;

        if (cmd.DataContext is Drinks deleteDrink)
        {
            Drinks.Remove(deleteDrink);
        }
    }

    private void CmdAddDrink_Clicked(object sender, RoutedEventArgs e)
    {
        string typeSelection = ((Drinks)DrinkTypeComboBox.SelectedItem).Type;

        Drinks.Add(new Drinks(typeSelection, DrinkNameTextBox.Text));
    }
}

饮料类具有饮料的类型和名称。     公共类饮料     {         私有字符串类型;         私人字符串名称;

    public Drinks(string type, string name)
    {
        this.type = type;
        this.name = name;
    }

    public string Type
    {
        get { return type; }

        set
        {
            if (type != value)
            {
                type = value;
            }
        }
    }

    public string Name
    {
        get { return name; }

        set
        {
            if (name != value)
            {
                name = value;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

假设您有您的物品:

public class Drinks
{
    //your properties, simplified for clarity
    public string Name {get;set;}
    public string Type {get;set;}

    //hey, a new one!
    public bool IsUserDefined {get;set;}
}

然后,当用户添加一个时:

private void CmdAddDrink_Clicked(object sender, RoutedEventArgs e)
{
    string typeSelection = ((Drinks)DrinkTypeComboBox.SelectedItem).Type;

    Drinks.Add(new Drinks(typeSelection, DrinkNameTextBox.Text)
    {
         IsUserDefined = true
    });
}

免责声明:从我的头顶开始;通常这意味着语法错误;为了清楚起见,删除了一些零件。

<!-- In your resources section of the XAML -->
<BooleanToVisibilityConverter x:Key="BoolToVis" />

<ListBox x:Name="DrinksListBox" ItemSource="{Binding Drinks}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Type}"/>
                <TextBlock Text="{Binding Name}"/>
                <Button x:Name="DrinkDeleteButton" 
                     Visibility="{Binding Path=IsUserDefined, 
                               Converter={StaticResource BoolToVis}}"/>
                    <!-- note: left out some attributes for clarity -->
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

应该可以解决问题。


顺便说一句,您似乎在混合一些典型的MVVM样式编码和代码隐藏编码。值得一提的是,在代码中使用ViewModel可能会受益。