Dynamo WPF Button on Node

So, an interoperability project plug-in I am trying to create a set of nodes which have a button on them. The idea is that, when the user presses the button, a windows form pops-up and you can select your desired output and press “Ok”. Next the nodes should return what you have selected. I am now stuck on the point where I can press the button and the form pops-up, but when I press “Ok” the node only returns “null” which is the default value.

Because I am using 3 classes (The Node class, the Customization class and the XAML) I don’t know what to assign where to let it function.

Below are the classes for the Node and the Node Customization

using System.Collections.Generic;
using Dynamo.Graph.Nodes;
using Dynamo.Controls;
using Dynamo.Wpf;
using Autodesk.DesignScript.Runtime;
using ProtoCore.AST.AssociativeAST;


namespace Dolly_for_Dynamo.Nodes
{
    /// <summary>
    /// This is the "Select Project" Node. It is a Class which inherits from the Node Model Base Class.
    /// </summary>
    [NodeName("Select Project")]
    [NodeDescription("Select the Project Directory which contains the Json files")]
    [OutPortNames("Project")]
    [OutPortTypes("string")]
    [OutPortDescriptions("The project directory")]
    [IsDesignScriptCompatible]
    public class ProjectSelector : NodeModel
    {
        //The Public constructor
        public ProjectSelector()
        {
            RegisterAllPorts();
        }

        //The Private property of the Class which represents the Output
        private string _outputPath;

        //The Public property of the Class which represents the Output
        public string OutputPath
        {
            get
            {
                return _outputPath;
            }
            set
            {
                _outputPath = value;
                RaisePropertyChanged("OutputPath");
                OnNodeModified(false);
            }
        }


        //The Public class methode to execute a function and get an output
        public IEnumerable<AssociativeNode> BuildOutputAst()
        {
            if (this.OutputPath != null)
            {
                return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildStringNode(this.OutputPath)) };
            }
            else
            {
                return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), AstFactory.BuildNullNode()) };
            }

        }
    }

    /// <summary>
    /// Node Customization Class. This will parse the UI for the ProjectSelector Class on the Node model
    /// </summary>
    [IsVisibleInDynamoLibrary(false)]
    class ProjectSelectorNodeView : INodeViewCustomization<ProjectSelector>
    {

        //The Public property of the Class which represents the Output
        public string OutputPath { get; set; }

        public void CustomizeView(ProjectSelector model, NodeView nodeView)
        {
            ProjectSelectorControls ui = new ProjectSelectorControls();
            model.OutputPath = ui.outputPath;
            nodeView.inputGrid.Children.Add(ui);
            
            ui.DataContext = model;
        }
        
        public void Dispose()
        {
        }
    }
}

And this is the XAML code so far

<UserControl x:Class="Dolly_for_Dynamo.Nodes.ProjectSelectorControls"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Dolly_for_Dynamo.Nodes"
             mc:Ignorable="d" Height="57.899" Width="186.259">
	<Grid HorizontalAlignment="Right" Width="154" Height="58" VerticalAlignment="Top" Margin="0,0,32.4,-0.4">
		<Grid.RowDefinitions>
			<RowDefinition Height="54*"/>
			<RowDefinition Height="7*"/>
			<RowDefinition Height="7*"/>
		</Grid.RowDefinitions>
		<Button
			Margin="0,0,33,17.6"
			Click="Button_Click"
			Content="Select Project"
			IsEnabled="True" BorderBrush="{x:Null}" Background="White" Foreground="Black"
			
		/>

	</Grid>
</UserControl>

With the Code behind it

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Autodesk.DesignScript.Runtime;
using Dolly_for_Dynamo.Functions;

namespace Dolly_for_Dynamo.Nodes
{
    /// <summary>
    /// Interaction logic for ProjectSelectorControls.xaml
    /// </summary>
    public partial class ProjectSelectorControls : System.Windows.Controls.UserControl
    {
        public string outputPath { get; set; }

        public ProjectSelectorControls()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            FolderBrowserDialog browser = new FolderBrowserDialog();
            if ((browser.ShowDialog() == DialogResult.OK))
            {
                //Harvest values from form and assign them to local variables
                outputPath = browser.SelectedPath;
                System.Windows.MessageBox.Show(outputPath);
            }

        }
    }
}

My question is what do I have to change to assign the FolderBrowserDialog.SelectedPath from the XAML to the ProjectSelector.OutputPath?

Thanks in advance

1 Like