A few dotnet list view question


#1

So far, I only have used datagridview.
One issue is that I can not have spinner without 3rd party dll.
Also, it was kinda slow with a lot of different cell types.

Then, I heerd ListView control is newer one.
So… my question is…

  1. Can I put different control for each cell?
    I need checkbo, dropdown, spinner, text, button.

  2. Is it faster then datagridview?

  3. any other think to consider?

Thanks!


#2

I always use WPF not winform.


#3

Interesting… I checked WPF.
I certainly like using XAML.

Then, which WPF should I use instead of DataGridView?

I guess it is better to put in dotnet form than mxs dialog?

Is there something like Subrollout in WPF?


#4
  • DataGrid.
  • You can use WPF window (dotnetobject “System.windows.window”) or use dotNet Control “Integration.ElementHost” inside mxs dialog.
  • Forget subrollout, just use WPF TabControl.

#5

This is an example to start:

global Window
(
	if heapSize < 256000000 do heapSize = 256000000 --256Mb
	
	-- Window
	if Window != undefined do Window.close()
	
	CompilerResults =
	(
		Source =
	"
		public class RowData
		{
			public bool Check { get; set; }
			public string Name { get; set; }
			public int Percent { get; set; }
		}
	"
		CompilerParameters = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
		CompilerParameters.GenerateInMemory = on
		CompilerResults = (dotnetobject "Microsoft.CSharp.CSharpCodeProvider").CompileAssemblyFromSource CompilerParameters #(Source)
	)
	
	XamlString = 
	"
	<Window
		xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"
		xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"
		Title=\"MainWindow\" Height=\"350\" Width=\"525\">
    <Grid Margin=\"10\">
    <TabControl>
        <TabItem Header=\"TabA\">
            <Label Content=\"Hello World!\"/>
        </TabItem>
        <TabItem Header=\"TabB\">
            <DataGrid Name=\"TheDataGrid\" AutoGenerateColumns=\"False\">
                <DataGrid.Columns>
                    <DataGridCheckBoxColumn Header=\"Include\" Binding=\"{Binding Include}\"/>
                    <DataGridTextColumn Header=\"Name\" Binding=\"{Binding Name}\"/>
                    <DataGridTemplateColumn Header=\"Percent\">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ProgressBar Value=\"{Binding Percent}\"/>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </TabItem >
        <TabItem Header=\"TabC\">
            <Label Content=\"Goodby World!\"/>
        </TabItem>
    </TabControl>
	</Grid>
	</Window>
	"
	Window = (dotnetclass "System.Windows.Markup.XamlReader").Parse XamlString
	TheDataGrid = Window.findname "TheDataGrid"
	for i = 1 to 10 do
	(
		RowData = CompilerResults.CompiledAssembly.createInstance "RowData"
		RowData.Check = true
		RowData.Name = i as string
		RowData.Percent = i * 10
		TheDataGrid.items.add RowData
	)
	-- Show Window
	(dotnetobject "System.Windows.Interop.WindowInteropHelper" Window).owner = dotnetobject "IntPtr" (windows.getMAXHWND())
	(dotnetclass "ManagedServices.AppSDK").ConfigureWindowForMax Window
	Window.show()
)

#6

Wow… this is so awesome.
I have some more question. :slight_smile:

The reason why I need something like Subrollout is my UI is 1 treeview that is always shown + bunch of different subtollouts which generated dynamically.
So, depends of what user select in tree view, you can only 2 - 30 whatever subrollout.

Can I generate XAML programmatically? since I need to change UI dynamically, I don’t think parsing string would work for me.

How would you handle all events? I can just generate UI with XAML then use addEvent for adding events? I have tons of events.

I also need to be able to set different cell type per cell since value could be a numer, string, bool, color. Could u show me the example?

  1. I saw you had asked how to use numericUpandDown in wpf. Did yo u figure out?

Thanks!


#7

1 - You can use WPF Expander instead of Subrollout.
2 - Yes, But depend of the case you may had to write more line of codes.
3 - Yes, You can add event handelers like winform, but the only difference is you should always use SetLifeTimeControl after that.

	fn DoPrint Sender Arg =
	(
		print Sender
	)
	dotNet.AddEventHandler MyButton #Click DoPrint
	dotNet.SetLifeTimeControl MyButton #dotNet 

4 - There is some built-in column types for example string, bool, url, … But as I showed you in the example (Progressbar) you can add almost any control.
5 - Yes, I created my own custom control.


#8

Thanks. I’m digging WPF all day long.
Looks very promising.

SO… I figured out how to build xml that looks like xaml and parse it. so, that’s good.

Question about update UI.

As I said, I will have a treeview which will trigger what kinds of Expander I would need to display.

I guess I can put treeview in a panel and expanders in other panel. But, is it possible to update UI;s in only one panel? I dont want to redraw the entire UI all the time.

Also I think I can embed event in xaml, right?


#9

tried this.

Click=“btnClick”

I got this error.

Runtime error: .NET runtime exception: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
– MAXScript callstack:


#10

Instead of adding and removing Expanders, you can set their Visibility property to the Collapsed.
Well, i’s not a good idea to add events in xaml. because C# code and Xaml code that we generated are not in the same assembly and don’t know each other. Just use a name for the control, Then find it by using “findname” method and add event handlers by using the msx code.


#11

Here is another example:

global Window
(
	if heapSize < 256000000 do heapSize = 256000000 --256Mb
	
	-- Window
	if Window != undefined do Window.close()
	
	XamlString = 
	"
	<Window
		xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"
		xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"
		Title=\"MainWindow\" Height=\"350\" Width=\"525\">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width=\"*\" />
            <ColumnDefinition Width=\"5\" />
            <ColumnDefinition Width=\"*\" />
        </Grid.ColumnDefinitions>
        <TreeView>
            <TreeViewItem Header=\"Root\" IsExpanded=\"True\" Padding=\"5\">
                <Button Content=\"Trigger Red\" Name=\"TheTriggerRed\" Padding=\"5\" Margin=\"5\"/>
                <Button Content=\"Trigger Green\" Name=\"TheTriggerGreen\" Padding=\"5\" Margin=\"5\"/>
                <Button Content=\"Trigger Blue\" Name=\"TheTriggerBlue\" Padding=\"5\" Margin=\"5\"/>
            </TreeViewItem>
        </TreeView>
        <GridSplitter Grid.Column=\"1\" Width=\"5\" HorizontalAlignment=\"Stretch\"/>
        <StackPanel Grid.Column=\"2\">
            <Expander Padding=\"5\" IsExpanded=\"True\" Background=\"Red\" Visibility=\"Collapsed\" Name=\"TheExpanderRed\">
                <Button Content=\"****\"/>
            </Expander>
            <Expander Padding=\"5\" IsExpanded=\"True\" Background=\"Green\" Visibility=\"Collapsed\" Name=\"TheExpanderGreen\">
                <Slider/>
            </Expander>
            <Expander Padding=\"5\" IsExpanded=\"True\" Background=\"Blue\" Visibility=\"Collapsed\" Name=\"TheExpanderBlue\">
                <Button Content=\"####\"/>
            </Expander>
        </StackPanel>
    </Grid>
	</Window>
	"
	Window = (dotnetclass "System.Windows.Markup.XamlReader").Parse XamlString
	TheTriggerRed = Window.findname "TheTriggerRed"
	TheTriggerGreen = Window.findname "TheTriggerGreen"
	TheTriggerBlue = Window.findname "TheTriggerBlue"
	TheExpanderRed = Window.findname "TheExpanderRed"
	TheExpanderGreen = Window.findname "TheExpanderGreen"
	TheExpanderBlue = Window.findname "TheExpanderBlue"
	
	fn SetExpanderVisibility Nam =
	(
		case Nam of
		(
			"TheTriggerRed":
			(
				TheExpanderRed.Visibility = TheExpanderRed.Visibility.Visible
				TheExpanderGreen.Visibility = TheExpanderRed.Visibility.Collapsed
				TheExpanderBlue.Visibility = TheExpanderRed.Visibility.Collapsed
			)
			"TheTriggerGreen":
			(
				TheExpanderRed.Visibility = TheExpanderRed.Visibility.Collapsed
				TheExpanderGreen.Visibility = TheExpanderRed.Visibility.Visible
				TheExpanderBlue.Visibility = TheExpanderRed.Visibility.Collapsed
			)
			"TheTriggerBlue":
			(
				TheExpanderRed.Visibility = TheExpanderRed.Visibility.Collapsed
				TheExpanderGreen.Visibility = TheExpanderRed.Visibility.Collapsed
				TheExpanderBlue.Visibility = TheExpanderRed.Visibility.Visible
			)
		)
	)
	
	fn OnClick Sender Arg =
	(
		SetExpanderVisibility Sender.name
	)
	for b in #(TheTriggerRed,TheTriggerGreen,TheTriggerBlue) do
	(
		dotNet.AddEventHandler b #Click OnClick
		dotNet.SetLifeTimeControl b #dotNet
	)
	
	-- Show Window
	(dotnetobject "System.Windows.Interop.WindowInteropHelper" Window).owner = dotnetobject "IntPtr" (windows.getMAXHWND())
	(dotnetclass "ManagedServices.AppSDK").ConfigureWindowForMax Window
	Window.show()
)

#12

I suggest you to do your tests inside VisualStudio(WPF Application), And then convert it inside mxs,


#13

Thanks.

I guess I need to try to convett a subrollout as a WPF form and putin elementhost…


#14

You can’t embed 3dsMax’s controls inside WPF.