0

This question is a continuation of the pregoing one.( How can I combine some UserControls in SilverLight?) I have 3 view models with different colour properties.

How can I create elements of User Control with trigger invoke method after pressing the button on the element.

Here is a code of this element that I have upgrade with the trigger action.

<UserControl x:Class="SilverlightApplication14.NodePicture"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:SilverlightApplication14"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity">


    <Grid x:Name="LayoutRootNodePicture" Height="100" Width="100"
      HorizontalAlignment="Center">
        <Canvas x:Name="ParentCanvas" Background="{Binding NodeColor}" Width="100" Height="100" >
        </Canvas>
        <Image HorizontalAlignment="Center"
                   Source="add.png"
                   Stretch="Fill"
                   Width="16"
                   VerticalAlignment="Top"
                   Margin="0,0,2,2"
                   Height="16" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseLeftButtonDown">
                    <local:Add />
                </i:EventTrigger>
            </i:Interaction.Triggers>

        </Image>
    </Grid>
</UserControl>

And the code with the trigger action

namespace SilverlightApplication14
{
    public class Add : TriggerAction<FrameworkElement>
    {

        protected override void Invoke(object parameter)
        {
            var vm = AssociatedObject.DataContext as NodeViewModel;
            if (vm != null)
            {
                if (vm.Nodes == null)
                {
                    vm.Nodes = new ObservableCollection<NodeViewModel>();
                }
                var child = new NodeViewModel { NodeColor = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };
                vm.Nodes.Add(child);
            }

            }
        }
    }

Updated code:

       <Grid>
  <Grid.Resources>
            <Style  x:Key="myStyle" TargetType="ListBoxItem">
                <Setter Property="Background" Value="Khaki" />
                <Setter Property="Foreground" Value="DarkSlateGray" />
                <Setter Property="Margin" Value="5" />
                <Setter Property="FontStyle" Value="Italic" />
                <Setter Property="FontSize" Value="14" />
                <Setter Property="BorderBrush" Value="DarkGray" />
            </Style>
        </Grid.Resources>

        <ListBox ItemsSource="{Binding Nodes}" ItemContainerStyle="{StaticResource myStyle}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                <local:NodePicture DataContext="{Binding}" />


            </DataTemplate>
            </ListBox.ItemTemplate>
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>

    </ListBox>
        </Grid>

Is there a simple (or a right way ) way of doing this?

Community
  • 1
  • 1
revolutionkpi
  • 2,632
  • 10
  • 45
  • 84
  • Actually the Add TriggerAction works, you can get convinced of this if you insert a debug breakpoint in the Invoke method. Explain what you expected and what actually happens that differs from your desired result. – vortexwolf Sep 29 '11 at 10:29
  • As I understand new elements appear over previous elements, But not with that colour as I want.Is it possible use Stackpanel, Grid or Canvas instead of ListBox?@ vorrtex – revolutionkpi Sep 29 '11 at 11:38
  • Maybe they will be visible when the possibility to move elements would be added? @ vorrtex – revolutionkpi Sep 29 '11 at 11:52
  • You haven't posted the code of the ListBox, so I don't know why new elements overlap previous elements. About color, it is hard coded in the trigger action. You can change it there or use a property. – vortexwolf Sep 29 '11 at 12:31
  • I have updated my code, but when I have Grid I get only 1 element on the page, when I have Canvas - the same like without ItemsPanel.@vorrtex – revolutionkpi Sep 29 '11 at 13:36
  • What is this code? – Bryant Sep 29 '11 at 15:52
  • How are you arranging the Nodes in the Canvas? Maybe you should rephrase the question about how to best accomplish what you're trying to do instead of trying to make this code work. – Bryant Sep 29 '11 at 15:54
  • This line was commented out, so I will delete it @ Bryant – revolutionkpi Sep 29 '11 at 16:36

1 Answers1

1

It is preferable to work with business-logic in view models, whereas triggers are intended for working with UI. I would change the trigger to a command:

<Button Command="{Binding AddCommand}">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Image ... />
        </ControlTemplate>
    </Button.Template>
 </Button>

When a user clicks the button, the AddCommand is invoked. It can be implemented in the view model so:

public class NodeViewModel
{
    public NodeViewModel()
    {
        this.AddCommand = new RelayCommand(obj => { /* do something */ });
    }

    public RelayCommand AddCommand { get; private set; }
    //...
}

The RelayCommand class is one of the possible implementations and it can be downloaded with the MVVM Light framework here.

vortexwolf
  • 13,967
  • 2
  • 54
  • 72