Wpf customControl binding controls DataTemplate button

I'm new to WPF, so I have tied to some binding on my clickcontrol button.

I have a textbox with watermark and selctedItems properties. Control if selecteditems! = Null displays them in the control like this:

link to the picture [ http://s29.postimg.org/p25qgqzwn/image.jpg> [1 ]

Now I need to connect the X buttons to remove this item from the selected source. I'm trying to do this in the OnApplyTemplate method, but I don't know how to get to this button in the controls in order to attach a mouse event.

my Xaml

<Style TargetType="{x:Type local:TextBoxPicker}">
    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
    <Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
    <Setter Property="HorizontalContentAlignment" Value="Left"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="AllowDrop" Value="true"/>
    <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
    <Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
    <Setter Property="WatermarkTemplate" Value="{StaticResource DefaultWatermarkTemplate}"/>
    <Setter Property="SelectedItemsTemplate" Value="{StaticResource DefaultSelectedItemsTemplate}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:TextBoxPicker}">
                <Grid>
                    <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
                        <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                    </Border>
                    <Border BorderBrush="Red" BorderThickness="1">
                        <ContentControl x:Name="PART_WatermarkHost"
                                Content="{TemplateBinding Watermark}"
                                ContentTemplate="{TemplateBinding WatermarkTemplate}"
                                VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                IsHitTestVisible="False"
                                Margin="{TemplateBinding Padding}"
                                Visibility="Collapsed" />
                    </Border>

                    <Border BorderBrush="Green" BorderThickness="1">
                        <ItemsControl x:Name="PART_SelectedItemsHost"
                                ItemsSource="{TemplateBinding SelectedItems}"
                                ItemTemplate="{TemplateBinding SelectedItemsTemplate}"
                                VerticalAlignment="Stretch"
                                HorizontalAlignment="Stretch"                                                                      
                                Margin="{TemplateBinding Padding}"
                                Visibility="Visible">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapPanel>
                                    </WrapPanel>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                        </ItemsControl>

                    </Border>
                </Grid>
               ....
            </ControlTemplate>
        </Setter.Value>
    </Setter>

      

and my ItemTemplate looks like this

xaml:

<DataTemplate x:Key="DefaultSelectedItemsTemplate" >
    <Border x:Name="selectedItemBorder" BorderBrush="Gray" BorderThickness="1" CornerRadius="5" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Margin="5,1,1,1">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="15"/>
            </Grid.ColumnDefinitions>
            <!--<TextBlock Grid.Column="0" Text="{Binding RelativeSource={RelativeSource Self}, Path=Ime}" Margin="5,0,3,0"></TextBlock>-->
            <TextBlock Grid.Column="0" Text="{Binding}" Margin="5,0,3,0"></TextBlock>
            <Button x:Name="PART_selectedItemButton" BorderThickness="0" Grid.Column="1" >X</Button>
        </Grid>
    </Border>
</DataTemplate>

      

.cs code

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        ItemsControl selectedItem = GetTemplateChild("PART_SelectedItemsHost") as ItemsControl;

        if (selectedItem != null)
        {
            selectedItem.MouseLeftButtonDown += new MouseButtonEventHandler(selectedItemBorder_MouseLeftButtonDown);

            // blind click on X buttons in ItemsControl
        }

    }

      

so how can I bind the "X" button on code items?

+1


source to share


2 answers


First, let's look at a model with an ObservableCollection and a command that will execute X:

private ObservableCollection<string> items = new ObservableCollection<string>() { "One", "Two", "Three" };
    public ObservableCollection<String> Items
    {
        get
        {
            return items;
        }
        set
        {
            items = value;
            NotifyPropertyChanged();
        }
    }

    public Command<String> DeleteItem
    {
        get
        {
            return new Command<string>((item) =>
            {
                if (items.Contains(item))
                {
                    items.Remove(item);
                }
                NotifyPropertyChanged("Items");
            });
        }
    }

      

Now the XAML:

The resources where it is bound to the "parent" datacontext is an easy way to find out where the binding is happening:



<Page.Resources>
    <DataTemplate x:Key="DefaultSelectedItemsTemplate" >
        <Border x:Name="selectedItemBorder" BorderBrush="Gray" BorderThickness="1" CornerRadius="5"  Margin="5,1,1,1">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="15"/>
                </Grid.ColumnDefinitions>
                <!--<TextBlock Grid.Column="0" Text="{Binding RelativeSource={RelativeSource Self}, Path=Ime}" Margin="5,0,3,0"></TextBlock>-->
                <TextBlock Grid.Column="0" Text="{Binding}" Margin="5,0,3,0"></TextBlock>
                <Button x:Name="PART_selectedItemButton" BorderThickness="0" Grid.Column="1" Command="{Binding DataContext.DeleteItem, ElementName=ItemsControlInstance}" CommandParameter="{Binding}">X</Button>
            </Grid>
        </Border>
    </DataTemplate>
</Page.Resources>

      

And finally itemcontrol:

<ItemsControl x:Name="ItemsControlInstance" ItemTemplate="{StaticResource DefaultSelectedItemsTemplate}" ItemsSource="{Binding Items}"/>

      

+1


source


Finally I managed to get it to work, with help and guidance from Jaun, it still didn't work (I tried 10 different things probably and it was in the DataContext .. it was never bound.

So, on my OnApplyTemplate override, I added this.DataContext = this ... so I skipped that part.

I used AttachedCommandBehavior (nuget) for command



code:

public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        this.DataContext = this;

        ItemsControl itmControl = GetTemplateChild("PART_SelectedItemsHost") as ItemsControl;

        if (itmControl != null)
        {
            itmControl.MouseLeftButtonDown += new MouseButtonEventHandler(itmControl_MouseLeftButtonDown);

            // blind click on X buttons in ItemsControl
        }

    }

      

0


source







All Articles