VtkActor is not displayed on WPF project - c#

I am trying to load a RenderWindowControl from vtk libraries on my WPF project using ActiViz.NET and Visual Studio 2013. The library works fine since I did a new project just to practice on it but when I try to integrate it into my work, the actor is not shown. This is my code:
MainWindow.xaml:
<Window x:Class="myProject.Views.MainWindow"
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:VtkTab="clr-namespace:myProject.Views.UITabs.VtkTab"
x:Name="Mainwindow"
MinHeight="600"
MinWidth="800"
Title="{Binding Title}"
Height="720"
Width="1280"
Icon="{StaticResource ApplicationIcon}"
Loaded="OnLoaded"
DataContext="{Binding Main, Source={StaticResource ViewModelLocator}}"
Style="{StaticResource WindowStyle}"
mc:Ignorable="d">
<DockPanel>
<TabControl>
....
....
<VtkTab:VtkTabView />
....
....
</TabControl>
</DockPanel>
</Window>
VtkTabView.xaml:
<UserControl x:Class="myProject.Views.UITabs.VtkTab.VtkTabView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vtk="clr-namespace:Kitware.VTK;assembly=Kitware.VTK"
Height="480" Width="640">
<WindowsFormsHost Name="Wfh">
<vtk:RenderWindowControl x:Name="RenderControl" />
</WindowsFormsHost>
</UserControl>
VtkTabView.xaml.cs:
public partial class UITabView
{
protected static Random _random = new Random();
vtkActor actor = vtkActor.New();
public VtkTabView()
{
InitializeComponent();
var sphere = vtkSphereSource.New();
sphere.SetThetaResolution(8);
sphere.SetPhiResolution(16);
var shrink = vtkShrinkPolyData.New();
shrink.SetInputConnection(sphere.GetOutputPort());
shrink.SetShrinkFactor(0.9);
var move = vtkTransform.New();
move.Translate(_random.NextDouble(), _random.NextDouble(), _random.NextDouble());
var moveFilter = vtkTransformPolyDataFilter.New();
moveFilter.SetTransform(move);
moveFilter.SetInputConnection(shrink.GetOutputPort());
var mapper = vtkPolyDataMapper.New();
mapper.SetInputConnection(moveFilter.GetOutputPort());
// The actor links the data pipeline to the rendering subsystem
actor.SetMapper(mapper);
actor.GetProperty().SetColor(1, 0, 0);
RenderControl.Load += RenderWindowControlOnLoad;
}
void RenderWindowControlOnLoad(object sender, EventArgs e)
{
var renderer = RenderControl.RenderWindow.GetRenderers().GetFirstRenderer();
renderer.AddActor(actor);
renderer.SetBackground(0, 1, 0);
renderer.Render();
}
}
As you can see, in the method RenderWindowControlOnLoad (VtkTabView.xaml.cs) I take the actor (a Sphere) and I add it to the render declared into the WPF but it is not displayed. I tried to change the background color and call to render just in case but it's still not working :(

Call
RenderControl.RenderWindow.Render();
instead of
renderer.Render();

Related

How to add some of my code to xaml property ResizeMode= CanResizeWithGrip or whenever it is called

Hi at the begining of this question i want to say that i'm beginer and thing i've done here could prolly be done better but i'm still learnig. i want to set a value of some variable that contains the actual width of grid, and whenever i resize my window obviously this width change and I don't know how to access it. What i want to do ? Just want my progress bar to scale up or down when resizing
Here is some code
<Window x:Class="Lista6.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Lista6"
mc:Ignorable="d"
Title="MainPage" Height="650" Width="1000"
Background="#36393F"
ResizeMode="CanResizeWithGrip"
Icon="/img/Ikonka2.png"
WindowStyle="None">
///other xaml code
<ProgressBar Foreground="White"
Value="50"
BorderThickness="0"
Background="Gray"
Height="5"
Width="{Binding Path=ProgresBarWidth[0], Mode=OneWay}"/>
</StackPanel>
</Grid>
</Grid>
</Window>
ObservableCollection<double> width = new ObservableCollection<double> { };
public ObservableCollection<double> ProgresBarWidth
{
get
{
return width;
}
set
{
width = value;
}
}
public AppOperator()
{
width.Add(0);
}
private void ProgresbarWidthSetter()
{
MainPage mp = new MainPage();
width[0] = mp.MusicBar.Width;
}
Here as u can see i ve binded progres bar width to ObservColl property, and i want to call it when im resizing my window but i ve no idea how to do that.
Thanks for any help and wish u all good.

Why is the chart not updating

I'm using C# library LiveCharts.wpf's CartesianChart to make a chart in a wpf application. The Chart should be updated in Real-Time and I don't understand why it isn't working.
Here is my simple mainwindow, it makes a Graderview
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="13*" x:Name="LeftColoumn"/>
<ColumnDefinition Width="12*" x:Name="RightColumn"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="12*" x:Name="UpperRow"/>
<RowDefinition Height="12*" x:Name="LowerRow"/>
</Grid.RowDefinitions>
<local:GraderView Grid.ColumnSpan="1">
</local:GraderView>
</Grid>
Here is the wpf usercontrol graderView.cs. In the constructor it asynchronously starts a simulation. As this simulation progresses the event handler OnUpdateChartView gets called whenever new values are available.
public partial class GraderView : UserControl
{
public ChartValues<int> GraderOutputCount { get; set; }
public string[] GraderLabels { get; set; }
public Grader Grader { get; set; }
public GraderView()
{
InitializeComponent();
GraderOutputCount = new ChartValues<int>() { 1, 2, 3 };
GraderLabels = new string[20];
Simulator simulator = new Simulator();
simulator.Simulate();
Grader = simulator.Grader;
Grader.UpdateChartView += OnUpdateChartView;
DataContext = this;
}
//Event handler
void OnUpdateChartView(object sender, EventArgs e)
{
Trace.WriteLine("OnUpdateChartView got called");
GraderOutputCount = new ChartValues<int>(Grader.SortedOutputConveyors.Select(x => x.Item2.Count));
GraderLabels = Grader.SortedOutputConveyors.Select(x => x.Item1).ToArray();
for (int i = 0; i < GraderLabels.Length; i++)
{
Trace.WriteLine($"label:{GraderLabels[i]} amount:{GraderOutputCount[i]}");
}
}
}
Because of the Trace.Writelines I was able to verify that the event handler does get called when the app is running. This is for example what appears in the output window:
OnUpdateChartView got called
label:9,5 - 10,5 amount:4
label:8,5 - 9,5 amount:7
label:7,5 - 8,5 amount:9
label:6,5 - 7,5 amount:10
label:5,5 - 6,5 amount:7
label:4,5 - 5,5 amount:8
label:3,5 - 4,5 amount:7
label:2,5 - 3,5 amount:8
label:1,5 - 2,5 amount:7
label:0,5 - 1,5 amount:6
Here is the xaml of this WPF usercontrol GraderView. The Bindings appear correct to me. Values to GraderOutputCount and labels to GraderLabels.
<UserControl x:Class="WpfApp1.GraderView"
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:WpfApp1"
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" d:DataContext="{d:DesignInstance local:GraderView}">
<Grid>
<lvc:CartesianChart>
<lvc:CartesianChart.Series>
<lvc:ColumnSeries Title="Grader" Values="{Binding GraderOutputCount}"/>
</lvc:CartesianChart.Series>
<lvc:CartesianChart.AxisX>
<lvc:Axis Title="WeightClass" Labels="{Binding GraderLabels}"/>
</lvc:CartesianChart.AxisX>
<lvc:CartesianChart.AxisY>
<lvc:Axis Title="BoxCount" />
</lvc:CartesianChart.AxisY>
</lvc:CartesianChart>
</Grid>
My expected result was to first get the 1, 2, 3 that I put in the constructor of the graderview and then as the simulation progresses the chart would update automatically to the newer values in GraderOutputCount and Graderlabels. This is not what actually happens. The chart just doesn't update at all. Can anybody tell me what I am doing wrong here? Thanks in advance
What it looks like
I have found why the problem occured.
I changed
GraderOutputCount = new ChartValues<int>(Grader.SortedOutputConveyors.Select(x => x.Item2.Count));
To
GraderOutputCount.Clear();
foreach(var num in Grader.SortedOutputConveyors.Select(x => x.Item2.Count))
{
GraderOutputCount.Add(num);
}

How can I retrieve coordinates on a mouse click with ViewportPointToLocation?

I'm using Bing map WPF control SDK to try retrieving coordinates and printing them
I've managed to retrieve the coordinates of the center of the current LocationRect using an EventHandler associated with pressing the arrows
I've tried employing the same concept with mouse clicking event handlers but it didn't work, first I've registered the event using the += notation as follows:
public MainWindow()
{
InitializeComponent();
MainMap.Mode = new AerialMode(true);
MainMap.Focus();
MainMap.Culture = "ar-sa";
MainMap.MouseDoubleClick += new MouseButtonEventHandler(MapWithPushpins_MouseDoubleClick);
}
private void MapWithPushpins_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
e.Handled = true;
Point mousePosition = e.GetPosition(this);
Location pinLocation = MainMap.ViewportPointToLocation(mousePosition);
Pushpin pin = new Pushpin();
pin.Location = pinLocation;
Coordinates.Text = pinLocation.Longitude.ToString();
MainMap.Children.Add(pin);
}
And here's the XAML file:
<Window x:Class="Ornina.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF"
xmlns:local="clr-namespace:Ornina"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid VerticalAlignment="Top" >
<m:Map CredentialsProvider="AqCitpgSjIz_Sxd6AyI9Zm1rs1uRSG_G3Y7ebfok69ufB8W8uRdUtvheaRbz_10t" x:Name="MainMap" Center="36,38" ZoomLevel="16" Mode="AerialWithLabels" HorizontalAlignment="Center" VerticalAlignment="Top" Height="300" Width="500">
</m:Map>
</Grid>
<TextBlock x:Name="Coordinates">Coordinations</TextBlock>
</Grid>
</Window>
The program isn't responding with any thing, no exceptions, no errors
Your TextBlock is in front of your map, so the map doesn't receive the MouseDoubleClick event.
You can change the TextBlock to:
<TextBlock x:Name="Coordinates"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Text="Coordinations" />
So it's only in the top left corner and not in front of the whole map.
Or you can move it outside of the map entirely, in a different grid row or column.

Moving a triangle using given coordinate

I'm working on a project and I want to animate a rectangle to move a certain amount of coordinate that i have set earlier.
Ex: My rectangle is at the position (x=0,y=0). I want with a click of a button to make it move at position (x=150, y=230) in interval of 100 milliseconds. So with one click, it would go to (10,25) at first 100 milliseconds,(20,35) for second 100 milliseconds and so on until the rectangle reach the final position(x=150, y=230)...
I'm working with visual studio and blend on Visual C# wpf.
This is my progress of codes in code-behind file:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
var myRect = (Rectangle)this.FindName("myRect");
double x = Canvas.GetLeft(myRect);
double y = Canvas.GetTop(myRect);
Canvas.SetLeft(myRect,x+10);
Canvas.SetTop(myRect,y);
And this is in XAML code:
<Window x:Class="move.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:move"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<Border BorderThickness="1" BorderBrush="Aqua">
<Canvas Name="PointCanvas" Width="500" Height="294" Margin="9,0,6,0">
<Rectangle x:Name="myRect" Fill="#FFF5F4F5" Height="39" Canvas.Left="170" Stroke="Black" Canvas.Top="89" Width="89"/>
</Canvas>
</Border>
<Button Name="Move" Click="Button_Click">Move</Button>
</StackPanel>

Loading image from the web at runtime in WPF

I'm trying to load an image from an url in WPF in a very simple way, but it's not working. Any help ? The code is below :
Main XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="279*"></RowDefinition>
<RowDefinition Height="41*">
</RowDefinition>
</Grid.RowDefinitions>
<Image x:Name="image1" Grid.Row="0"></Image>
<TextBox Grid.Row="1" Margin="0,0,10,0"></TextBox>
</Grid>
</Window>
Code-behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri("http://www.clipartkid.com/images/817/pic-of-german-flag-clipart-best-VkuN37-clipart.jpeg");
bi.EndInit();
//var img = new Image();
image1.Source = bi;
}
}
Funny indeed! Works alright at my other laptop now. Must be something with the firewall settings. And yeps, I've made things even simpler now. Binding the source of the image in XAML to just a string property I've set in a ViewModel class.
<Image x:Name="image1" Source ="{Binding MyPic}" Grid.Row="0"></Image>
class MyViewModel
{
public string MyPic {
get { return #"http://www.clipartkid.com/images/817/pic-of-german-flag-clipart-best-VkuN37-clipart.jpeg"; }
}
}
Thanks for the responses, and sorry for the confusion.
-Ron

Categories