3

I'm starting to develop for UWP. I'm trying to create a ListView populated with x:bind. Now I want to create a button on all single items for delete them. Something like Windows 10 Mail:

I have created that:

enter image description here

<ListView x:Name="listActivity" ItemsSource="{x:Bind list}" Grid.Column="0" Header="Activity List" HorizontalAlignment="Center" Width="auto" IsItemClickEnabled="True" ItemClick="showDel">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="vm:Activity">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="3*"/>
                    <ColumnDefinition Width="1*"/>
                </Grid.ColumnDefinitions>
                <TextBlock x:Name="txt" Text="{x:Bind name}" Grid.Column="0"/>
                <Button x:Name="delItem" Click="delActivity" Grid.Column="1" Visibility="Collapsed" Background="Transparent" Margin="100, 0, 0, 0">
                    <SymbolIcon Symbol="Delete"/>
                </Button>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

I want to change the visibility of delItem button, but from C# I can't call it with set Name. How I can do that?

Salah Akbari
  • 39,330
  • 10
  • 79
  • 109
user2625557
  • 31
  • 1
  • 4
  • To get a button inside a `ListView.ItemTemplate` and change it's properties in code you should use `FrameworkTemplate.FindName Method`. Just like this answer: http://stackoverflow.com/a/34118343/2946329 – Salah Akbari Dec 07 '15 at 15:27
  • I also suggested what you do for missing `FindName`. You should use `FindDescendant` that I suggested in that answer. – Salah Akbari Dec 07 '15 at 18:28
  • Thank you very much seems to work well: D – user2625557 Dec 07 '15 at 22:27
  • Possible duplicate of [ListBox items return string, when DataTemplate is Button](http://stackoverflow.com/questions/34117944/listbox-items-return-string-when-datatemplate-is-button) – Salah Akbari Dec 27 '15 at 15:53

1 Answers1

2

I recommend to perform this operation by using binding.

a) Add a new property to your class Activity named Visible

public class Activity : INotifyPropertyChanged
{
    public string Name { get; set; }

    private bool _visible; 
    public bool Visible {
        get { return _visible; }
        set
        {
            _visible = value;
            RaisePropertyChanged("Visible");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}

b) Declare also a new class to convert boolean to visibility

public class BooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return value is Visibility && (Visibility)value == Visibility.Visible;
    }
}

c) And finally update your binding. Don't forget the OneWay mode setting.

<Page.Resources>
    <local:BooleanToVisibilityConverter x:Key="VisibilityConverter"/>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView ItemsSource="{x:Bind Activities}">
        <ListView.ItemTemplate>
            <DataTemplate x:DataType="local:Activity">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="3*"/>
                        <ColumnDefinition Width="1*"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock x:Name="txt" Text="{x:Bind Name}" Grid.Column="0"/>
                    <Button x:Name="delItem" Click="delItem_Click" Grid.Column="1" Visibility="{x:Bind Visible, Mode=OneWay, Converter={StaticResource VisibilityConverter}}" Background="Transparent" Margin="100, 0, 0, 0">
                        <SymbolIcon Symbol="Delete"/>
                    </Button>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

You can now access the Visibility or your control directly by code. Full code below for reference.

using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace App1
{
public sealed partial class MainPage : Page
{ 
    public List<Activity> Activities { get; set; }

    public MainPage()
    {
        this.InitializeComponent();

        Activities = new List<Activity>();
        Activities.Add(new Activity { Name = "Activity1", Visible = true });
        Activities.Add(new Activity { Name = "Activity2", Visible = false });
    }

    private void delItem_Click(object sender, RoutedEventArgs e)
    {
        Activities.First().Visible = false;
    }
}

public class BooleanToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return value is Visibility && (Visibility)value == Visibility.Visible;
    }
}

public class Activity : INotifyPropertyChanged
{
    public string Name { get; set; }

    private bool _visible; 
    public bool Visible {
        get { return _visible; }
        set
        {
            _visible = value;
            RaisePropertyChanged("Visible");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}
}