student96
student96

Reputation: 345

Get index of data binding from ItemsControl

Is there any way to get the index of the data which is binded to the ItemsControl, when a button is clicked?

<ItemsControl  x:Name="ic_schranke" DataContext="{Binding Schranke}" >
                <ItemsControl.ItemTemplate>
                    <DataTemplate >

                        <Button Height="80" x:Name="btn_open" Click="btn_open_Click" HorizontalAlignment="Stretch" Style="{StaticResource TransparentStyle}">
                            <Grid HorizontalAlignment="Stretch">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="1*"/>
                                    <ColumnDefinition Width="2*"/>
                                    <ColumnDefinition Width="1*"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="1*"/>
                                    <RowDefinition Height="30*"/>
                                    <RowDefinition Height="1*"/>
                                </Grid.RowDefinitions>

                                <Rectangle x:Name="rect" Grid.ColumnSpan="3" Grid.Row="1" Opacity="0.65" Grid.Column="0" Fill="#FFCEEAFF"/>

                                <Border CornerRadius="25" Height="50" Width="50" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="1">
                                    <Border.Background>
                                        <ImageBrush ImageSource="/Assets/schranken.jpg" />
                                    </Border.Background>
                                </Border>

                                <TextBlock Name="schranken_name" Grid.Column="1" Grid.Row="1" Text="{Binding name}" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="ExtraLight" Foreground="Black" />
                            </Grid>
                        </Button>

                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

Here is the sample data which is binded to the IC:

 List<Schranke> elements;
        public UserPage()
        {
            this.InitializeComponent();

            elements = new List<Schranke>();
            for (var i = 1; i < 15; i++)
                elements.Add(new Schranke() { name = $"Schranke NR:{i}" });


            this.ic_schranke.ItemsSource = elements;


}

And here is the code in the button click event:

private async void btn_open_Click(object sender, RoutedEventArgs e)
        {
            Grid grid = (sender as Button).Content as Grid;



            //Debug.WriteLine($"content {tb.Text} clicked");
            var tmp_background = grid.Background;
            grid.Background = new SolidColorBrush(new Windows.UI.Color() { A = 255, R = 78, G = 170, B = 44 });
            VibrationDevice testVibrationDevice = VibrationDevice.GetDefault();
            testVibrationDevice.Vibrate(System.TimeSpan.FromMilliseconds(150));
            await Task.Delay(3000);
            grid.Background = tmp_background;
        }

Upvotes: 1

Views: 1200

Answers (1)

MichaelThePotato
MichaelThePotato

Reputation: 1525

Maybe something along the lines of this:

the presenter - put this in the data context

public class SchrankePresenter : INotifyPropertyChanged
{
    private List<Schranke> _elements;
    public List<Schranke> Elements
    {
        get { return _elements; }
        set
        {
            _elements = value;
            OnPropertyChanged("Elements");
        }
    }
    public ICommand ClickCommand { get; set; }

    private void OnPropertyChanged(string propName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public SchrankePresenter()
    {
        var elements = new List<Schranke>();
        for (var i = 1; i < 15; i++)
            elements.Add(new Schranke() { Name = $"Schranke NR:{i}" });

        Elements = elements;
        ClickCommand = new DelegateCommand(ClickAction);
    }

    public void ClickAction(Schranke item)
    {
        VibrationDevice.GetDefault().Vibrate(TimeSpan.FromMilliseconds(150));
    }
}

public class Schranke
{
    public string Name { get; set; }
}

the template:

<ListView ItemsSource="{Binding Elements}">

            <ListView.ItemTemplate>

                <DataTemplate>

                    <Button Height="80"
                            HorizontalAlignment="Stretch"
                            Command="{Binding ClickCommand}"
                            Style="{StaticResource TransparentStyle}">
                        <Grid HorizontalAlignment="Stretch">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="1*" />
                                <ColumnDefinition Width="2*" />
                                <ColumnDefinition Width="1*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="1*" />
                                <RowDefinition Height="30*" />
                                <RowDefinition Height="1*" />
                            </Grid.RowDefinitions>

                            <Rectangle x:Name="rect"
                                       Grid.Row="1"
                                       Grid.Column="0"
                                       Grid.ColumnSpan="3"
                                       Fill="#FFCEEAFF"
                                       Opacity="0.65" />

                            <Border Grid.Row="1"
                                    Grid.Column="0"
                                    Width="50"
                                    Height="50"
                                    HorizontalAlignment="Center"
                                    CornerRadius="25">
                                <Border.Background>
                                    <ImageBrush ImageSource="/Assets/schranken.jpg" />
                                </Border.Background>
                            </Border>

                            <TextBlock Name="schranken_name"
                                       Grid.Row="1"
                                       Grid.Column="1"
                                       HorizontalAlignment="Center"
                                       VerticalAlignment="Center"
                                       FontWeight="ExtraLight"
                                       Foreground="Black"
                                       Text="{Binding Name}" />
                        </Grid>
                    </Button>

                </DataTemplate>

            </ListView.ItemTemplate>

        </ListView>

you can do the background animation using a storyboard/visualstate

EDIT : regarding the DelegateCommand, it's a simple implementation I use for my WPF apps -

internal class DelegateCommand<T> : ICommand
{
    private Action<T> _clickAction;

    public DelegateCommand(Action<T> clickAction)
    {
        _clickAction = clickAction;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _clickAction((T)parameter);
    }
}

Upvotes: 1

Related Questions