How to bind image source [duplicate] - c#

This question already has an answer here:
Databindings don't seem to refresh
(1 answer)
Closed 6 years ago.
I am trying to bind image source, the thing is that:
I have a folder with a filesystemwatcher - each time a new image file is added to the folder - I'm getting the full path of the image and want to bind that to the source of the image control.
So the images will change automatically in the GUI everytime a new TIFF file is added to the folder.
This is what I've done:
XAML:
<Window x:Class="WpfApplication2.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:WpfApplication2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="414,159,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>
<Image x:Name="img1" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="100" RenderTransformOrigin="1.604,1.161" Source="{Binding ButtonImage}" />
</Grid>
</Window>
MainWindow.xaml.cs
private ImageSource b;
public ImageSource ButtonImage
{
get { return b; }
set
{
b = value;
}
}
private void button_Click(object sender, RoutedEventArgs e)
{
ButtonImage = new BitmapImage(new Uri(#"C:\Users\x\Desktop\1.tif"));
watch();
}
private void watch()
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = #"C:\Users\x\Desktop\ti";
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
watcher.Filter = "*.tif";
}
private void OnChanged(object source, FileSystemEventArgs e)
{
ButtonImage = new BitmapImage(new Uri(e.FullPath));
}

Raise property changed event in the property setter
public ImageSource ButtonImage
{
get { return b; }
set
{
b = value;
PropertyChanged("ButtonImage");
}
}
Create a viewmodel and move the property there and set the DataContext of your view to this viewmodel
If you are using code behind then don't use binding
Give a name to the Image
img.Source=value;

Related

RichTextBox becomes ReadOnly when binding it to content from inside FlowDocumentReader

Question: In the btnRevert_Click(...) event of the following code, how can we make the RichTextBox editable?
In my WPF .NET5 app, the btnTest_Click(...) event successfully displays the contents of a RichTextBox into a FlowDocumentReader (fdReader). Then the btnRevert_Click(...) event successfully takes the content back from fdReader and displays it back into RichTextBox, but it makes the RichTextBox ReadOnly.
I tested the scenario by entering simple text "This is a test" inside RichTextBox, and noted that the above back and forth scenario works fine except that the btnRevert_Click(...) event makes the text "This is a test" ReadOnly.
MainWindow.xaml:
<Window x:Class="Wpf_RTBFlowDocTest.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:Wpf_RTBFlowDocTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<DockPanel Name="mainPanel">
<ToolBar Name="mainToolBar" Height="30" DockPanel.Dock="Top">
<Button x:Name="btnTest" Content="Test" Click="btnTest_Click"/>
<Button x:Name="btnRevert" Content="Revert" Click="btnRevert_Click"/>
</ToolBar>
<RichTextBox Name="rtbTest" AcceptsTab="True"></RichTextBox>
<FlowDocumentReader x:Name="fdReader" Visibility="Collapsed">
<FlowDocument>
<Paragraph>Text inside paragraph.</Paragraph>
</FlowDocument>
</FlowDocumentReader>
</DockPanel>
</Grid>
</Window>
MainWindow.xaml.cs:
private void btnTest_Click(object sender, RoutedEventArgs e)
{
FlowDocument RTBflowDoc = rtbTest.Document;
rtbTest.Visibility = Visibility.Collapsed;
rtbTest.Document = new FlowDocument();
fdReader.Document = RTBflowDoc;
fdReader.Visibility = Visibility.Visible;
}
private void btnRevert_Click(object sender, RoutedEventArgs e)
{
FlowDocument fdReaderFlowDoc = fdReader.Document;
fdReader.Document = new FlowDocument();
rtbTest.IsReadOnly = false;
rtbTest.Document = fdReaderFlowDoc;
rtbTest.Visibility = Visibility.Visible;
}
The FlowDocumentReader provides a control to view a flow content (doesn't support edit).
The following lines in btnRevert_Click() method, from question above, just set rtbTest.Document to fdReader.Document:
FlowDocument fdReaderFlowDoc = fdReader.Document;
fdReader.Document = new FlowDocument();
rtbTest.Document = fdReaderFlowDoc;
But because of the FlowDocument in the FlowDocumentReader control doesn't support editing, the easiest way to obtain document from the FlowDocumentReader control for editing is to clone it like below:
private void btnRevert_Click(object sender, RoutedEventArgs e)
{
var range = new TextRange(fdReader.Document.ContentStart, fdReader.Document.ContentEnd);
if (!range.IsEmpty)
{
using (var stream = new MemoryStream())
{
range.Save(stream, DataFormats.XamlPackage);
var copyto = new TextRange(rtbTest.Document.ContentEnd, rtbTest.Document.ContentEnd);
copyto.Load(stream, DataFormats.XamlPackage);
}
}
rtbTest.Visibility = Visibility.Visible;
fdReader.Visibility = Visibility.Collapsed;
}

WPF-InkCanvas StrokeErased event not firing when I used inkcanvas1.Strokes.Erase statement in C#

When I use inkcanvas1.EditingMode is InkCanvasEditingMode.EraseByPoint it is erasing and also StrokeErased event firing.
but when I erase stroke through inkcanvas1.Strokes.Erase(); function then StrokeErased event is not firing. then how can I identify which stroke erased and which strokes are newly created. consider on my inkcanvas thousands of strokes. so I'm not able to maintain every added and removed strokes.
is there any other event or any solution.
I have a below sample WPF Inkcanvas code
XAML Code
<Window x:Class="MyWhiteBoard.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:MyWhiteBoard"
mc:Ignorable="d"
WindowState="Maximized"
Title="MainWindow" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<InkCanvas x:Name="inkcanvas1" Grid.Row="0" StrokeErased="inkcanvas1_StrokeErased" MouseMove="inkcanvas1_MouseMove"></InkCanvas>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Width="100" Height="50" Background="WhiteSmoke" Content="Draw" Click="drawInkClick"></Button>
<Button Width="100" Height="50" Background="WhiteSmoke" Content="Erase by Point" Click="EraseByPointsClick"></Button>
<Button Width="100" Height="50" Background="WhiteSmoke" Content="Stroke Erase" Click="StrokeEraseClick"></Button>
<Button Width="100" Height="50" Background="WhiteSmoke" Content="clear all" Click="clearAllClick"></Button>
</StackPanel>
</Grid>
</Window>
Code Behind C# code
public partial class MainWindow : Window
{
private bool IsStrokeEraseCalled = false;
public MainWindow()
{
InitializeComponent();
}
private void inkcanvas1_StrokeErased(object sender, RoutedEventArgs e)
{
// why this event is not calling when I use
//inkcanvas1.Strokes.Erase
}
private void EraseByPointsClick(object sender, RoutedEventArgs e)
{
inkcanvas1.EditingMode = InkCanvasEditingMode.EraseByPoint;
}
private void StrokeEraseClick(object sender, RoutedEventArgs e)
{
inkcanvas1.EditingMode = InkCanvasEditingMode.Select;
IsStrokeEraseCalled = !IsStrokeEraseCalled;
}
private void clearAllClick(object sender, RoutedEventArgs e)
{
inkcanvas1.Strokes.Clear();
}
private void inkcanvas1_MouseMove(object sender, MouseEventArgs e)
{
if (IsStrokeEraseCalled)
{
Point currentPoint = e.GetPosition((IInputElement)sender);
List<Point> enumrator = new List<Point>();
enumrator.Add(new Point(currentPoint.X, currentPoint.Y));
StylusShape EraseShape = (StylusShape)new RectangleStylusShape(100, 100, 0);
inkcanvas1.Strokes.Erase(enumrator, EraseShape);
}
}
private void drawInkClick(object sender, RoutedEventArgs e)
{
inkcanvas1.EditingMode = InkCanvasEditingMode.Ink;
}
}
Replace your StrokeEraseClick event with following code:
private void StrokeEraseClick(object sender, RoutedEventArgs e)
{
inkcanvas1.EditingMode = InkCanvasEditingMode.EraseByPoint;
inkcanvas1.EraserShape = new RectangleStylusShape(100, 100);
var editMode = inkcanvas1.EditingMode;
inkcanvas1.EditingMode = InkCanvasEditingMode.None;
inkcanvas1.EditingMode = editMode;
}
It will leave the current mode to InkCanvasEditingMode.EraseByPoint and allow you to erase defined area stokes. StrokeErased event will be fired every time you erase strokes using this approach.
try this
public MainWindow()
{
InitializeComponent();
inkcanvas1.Strokes.StrokesChanged += Strokes_StrokesChanged;
}
private void Strokes_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e)
{
StrokeCollection newlyAddedStroke = e.Added;
StrokeCollection oldRemovedStroke = e.Removed;
}
When you erase stroke through inkcanvas1.Strokes.Erase(); function then the StrokeErased event will not fire by default.
If you want to maintain added and removed strokes then you can handle it in inkcanvas1.Strokes.StrokesChanged event.
Or you should be in EraseByPoint Mode and use statement
inkcanvas1.EraserShape = new RectangleStylusShape(100, 100);
If you have bulk strokes on your inkcanvas then for maintaining every strokecollection every time is heavy then you have choice to add unique id to every stroke using ProperyData property.

How do I change window background image dynamically in WPF with a button click?

I want to change or "scroll through" different background images for the main window based on a button click. The number of different backgrounds will be dynamic and will be based on something like the number of images in a specific folder. So each time the program loads there could be a different number of backgrounds to scroll through.
I also want to be able to go back to the previous background image, so the whole thing kind of acts like a carousel. Example: the program loads and A.jpg is loaded as background image. I click the "Right" button and A.jpg slides off to the left, and then B.jpg slides in from the right to become the new background image. I click "Right" again and C.jpg slides in from the right. I then click "Left" and B.jpg slides back in from the left side, etc. etc.
Hopefully that makes sense. I'm quite new to XAML and WPF so just trying to figure out how I would go about doing this. Any help or guidance would be much appreciated. Thanks!
I would use a ListView and an ObservableCollection<string> in ViewModel. The ObservableCollection<string> contains a dynamic list of paths to the images. Be sure that the Build Action of the images is set to Resource. Then within the Background Property of Window place an ImageBrush where you bind the Source Property to the SelectedItem Property of ListView. The path strings of images follows a scheme you can find here: https://learn.microsoft.com/en-us/dotnet/framework/wpf/app-development/pack-uris-in-wpf
As desired (Images are BuildAction to Resource and copy if newer):
MainWindow.xaml
<Window x:Class="WinTest.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:WinTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:TestViewModel x:Key="viewModel"/>
<local:ImageConverter x:Key="converter"/>
</Window.Resources>
<Window.DataContext>
<Binding Source="{StaticResource viewModel}" IsAsync="True"/>
</Window.DataContext>
<Window.Background>
<ImageBrush ImageSource="{Binding SelectedImagePath, Converter={StaticResource converter}}"/>
</Window.Background>
<Grid Background="Transparent">
<ListView Background="Transparent" SelectedValue="{Binding SelectedImagePath, Mode=TwoWay}" ItemsSource="{Binding PathList}"/>
</Grid>
</Window>
TestViewModel.cs (Collection can used as string or Uri list. You have to instanciate a new Uri in Converter from value if you use strings)
public class TestViewModel : BasePropertyChangeNotification
{
public ObservableCollection<Uri> PathList
{
get;
private set;
}
public Uri SelectedImagePath
{
get { return this.selectedImagePath; }
set { this.SetProperty(ref this.selectedImagePath, value); }
}
private Uri selectedImagePath = new Uri("pack://application:,,,/Images/img1.jpg", UriKind.RelativeOrAbsolute);
public TestViewModel()
{
this.PathList = new ObservableCollection<Uri>
{
new Uri("pack://application:,,,/Images/img1.jpg", UriKind.RelativeOrAbsolute),
new Uri("pack://application:,,,/Images/img2.jpg", UriKind.RelativeOrAbsolute),
new Uri("pack://application:,,,/Images/img3.jpg", UriKind.RelativeOrAbsolute),
new Uri("pack://application:,,,/Images/img4.jpg", UriKind.RelativeOrAbsolute),
new Uri("pack://application:,,,/Images/img13.jpg", UriKind.RelativeOrAbsolute)
};
}
}
ImageConverter.cs
public class ImageConverter : IValueConverter
{
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture)
{
return new BitmapImage(value as Uri);
}
public object ConvertBack(
object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
}
That's all.
That's how you can do this ! I have tested it . You can apply animations for carousel type effects.
public MainWindow()
{
InitializeComponent();
myImagesList = new List<ImageBrush>();
ImageBrush myBrush1 = new ImageBrush(new BitmapImage(new Uri(#"C:\Users\Abdul Rehman\Desktop\1-Rao Hammas Folder\MY PROJECTS\StackOverFlowSolutions\StackOverFlowSolutions\Images\Capture.JPG")));
ImageBrush myBrush2 = new ImageBrush(new BitmapImage(new Uri(#"C:\Users\Abdul Rehman\\Desktop\1-Rao Hammas Folder\MY PROJECTS\StackOverFlowSolutions\\StackOverFlowSolutions\Images\\Apps-Dialog-Close-icon.png")));
ImageBrush myBrush3 = new ImageBrush(new BitmapImage(new Uri(#"C:\Users\Abdul Rehman\\Desktop\1-Rao Hammas Folder\MY PROJECTS\StackOverFlowSolutions\\StackOverFlowSolutions\Images\\Capture.JPG")));
ImageBrush myBrush4 = new ImageBrush(new BitmapImage(new Uri(#"C:\Users\Abdul Rehman\\Desktop\1-Rao Hammas Folder\MY PROJECTS\StackOverFlowSolutions\\StackOverFlowSolutions\Images\\Capture.JPG")));
ImageBrush myBrush5 = new ImageBrush(new BitmapImage(new Uri(#"C:\Users\Abdul Rehman\\Desktop\1-Rao Hammas Folder\MY PROJECTS\StackOverFlowSolutions\\StackOverFlowSolutions\Images\\Capture.JPG")));
myImagesList.Add(myBrush1);
myImagesList.Add(myBrush2);
myImagesList.Add(myBrush3);
myImagesList.Add(myBrush4);
myImagesList.Add(myBrush5);
MainWin.Background = myImagesList[index];
}
private int index = 0;
private List<ImageBrush> myImagesList;
private void NextBtn_Click(object sender, RoutedEventArgs e)
{
index++;
MainWin.Background = myImagesList[index];
}
private void PrevBtn_Click(object sender, RoutedEventArgs e)
{
index--;
MainWin.Background = myImagesList[index];
}
XAML
<Window x:Class="StackOverFlowSolutions.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="MainWin"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Name="NextBtn" Width="30" Height="20" Click="NextBtn_Click">Next</Button>
<Button Name="PrevBtn" Width="30" Height="20" Margin="297,111,176,180" Click="PrevBtn_Click">Prev</Button>
</Grid>
</Window>

WPF can't find resource

I have a question about finding resources in WPF, and I read the mechanism of finding resources from book.
It said that a UIElement will find its resources attribute first, if nothing fit then it will find its parent's resources attribute and so on, till application resources attribute.
I think it just like bubble routed event.
So I define a resource in stackpanel, here is the xaml.
<Window x:Class="DynamicResource.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:DynamicResource"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel x:Name="stackPanel">
<StackPanel.Resources>
<TextBlock x:Key="res1" Text="this is staticresource" Background="Beige"></TextBlock>
<TextBlock x:Key="res2" Text="this is dynamicresource" Background="DarkGoldenrod"></TextBlock>
</StackPanel.Resources>
<Button Margin="5,5,5,0" Content="{StaticResource res1}"></Button>
<Button Margin="5,5,5,0" Content="{DynamicResource res2}"></Button>
<Button x:Name="button" Margin="5,5,5,0" Content="refresh resource" Click="Button_Click"></Button>
</StackPanel>
Then I try to change dynamic resource in the button click event, here is xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//Can find target resource
//stackPanel.Resources["res1"] = new TextBlock() { Text = "this is new staticresource", Background = new SolidColorBrush(Colors.Tan) };
//stackPanel.Resources["res2"] = new TextBlock() { Text = "this it new dynamicresouce", Background = new SolidColorBrush(Colors.Magenta) };
//Can't find target resource
button.Resources["res1"] = new TextBlock() { Text = "this is new staticresource", Background = new SolidColorBrush(Colors.Tan) };
button.Resources["res2"] = new TextBlock() { Text = "this it new dynamicresouce", Background = new SolidColorBrush(Colors.Magenta) };
}
}
But the resource of button didn't change.
So what cause this happened, and how could to bubbly find resources.
you must set name for button and use this name in code behind
in xaml:
<Button Margin="5,5,5,0" Name="btnRes2" Content="{DynamicResource res2}"></Button>
in code behind :
private void Button_Click(object sender, RoutedEventArgs e)
{
btnRes2.Resources["res2"] = new TextBlock() { Text = "this it new dynamicresouce", Background = new SolidColorBrush(Colors.Magenta) };
}
this code work for DynamicResource.

KinectColorViewer SDK 1.7

I'm trying to make KinectColorViewer to work with SDK 1.7 but without success. I can display video picture only if I manually copy pixels from camera to Image element.
I have the following XAML:
<Page
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:k="http://schemas.microsoft.com/kinect/2013"
xmlns:WpfViewers="clr-namespace:Microsoft.Samples.Kinect.WpfViewers;assembly=Microsoft.Samples.Kinect.WpfViewers" x:Class="KinectD.Camera"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="500"
Title="Camera">
<Grid>
<k:KinectUserViewer k:KinectRegion.KinectRegion="{Binding ElementName=kinectRegion}" Height="100" HorizontalAlignment="Center" VerticalAlignment="Top" />
<k:KinectSensorChooserUI HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="sensorChooserUi" />
<k:KinectRegion x:Name="kinectRegion">
<Grid>
<k:KinectCircleButton Label="Menu" HorizontalAlignment="Right" Height="200" VerticalAlignment="Top" Click="MenuButtonOnClick" >
<StackPanel>
<Image Source="Images/smile.png" Height="30"/>
</StackPanel>
</k:KinectCircleButton>
</Grid>
</k:KinectRegion>
<WpfViewers:KinectColorViewer HorizontalAlignment="Left" Height="240" Margin="10,10,0,0" VerticalAlignment="Top" Width="320" Kinect="{Binding ElementName=sensorChooserUi, Mode=OneWay, Path=Kinect}"/>
</Grid>
And XAML.CS:
public partial class Camera : Page
{
#region "Kinect"
private KinectSensorChooser sensorChooser;
#endregion
public Camera()
{
this.InitializeComponent();
// initialize the sensor chooser and UI
this.sensorChooser = new KinectSensorChooser();
//Assign the sensor chooser with the sensor chooser from the mainwindow.
//We are reusing the sensorchoosing declared in the first window that can in contact with kinect
this.sensorChooser = Generics.GlobalKinectSensorChooser;
//subscribe to the sensorChooserOnKinectChanged event
this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
//Assign Kinect Sensorchooser to the sensorchooser we got from our static class
this.sensorChooserUi.KinectSensorChooser = sensorChooser;
// Bind the sensor chooser's current sensor to the KinectRegion
var regionSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
BindingOperations.SetBinding(this.kinectRegion, KinectRegion.KinectSensorProperty, regionSensorBinding);
}
private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args)
{
bool error = false;
if (args.OldSensor != null)
{
try
{
args.OldSensor.DepthStream.Range = DepthRange.Default;
args.OldSensor.SkeletonStream.EnableTrackingInNearRange = false;
args.OldSensor.DepthStream.Disable();
args.OldSensor.SkeletonStream.Disable();
args.OldSensor.ColorStream.Disable();
}
catch (InvalidOperationException)
{
// KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
// E.g.: sensor might be abruptly unplugged.
error = true;
}
}
if (args.NewSensor != null)
{
try
{
args.NewSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
args.NewSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
args.NewSensor.SkeletonStream.Enable();
}
catch (InvalidOperationException)
{
error = true;
// KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
// E.g.: sensor might be abruptly unplugged.
}
}
if (!error)
kinectRegion.KinectSensor = args.NewSensor;
}
private void MenuButtonOnClick(object sender, RoutedEventArgs e)
{
//Unsubscribe to the sensorchooser's event SensorChooseronkinectChanged
this.sensorChooser.KinectChanged -= SensorChooserOnKinectChanged;
(Application.Current.MainWindow.FindName("_mainFrame") as Frame).Source = new Uri("MainMenu.xaml", UriKind.Relative);
}
}
In tutorial I was following (http://channel9.msdn.com/Series/KinectQuickstart/Camera-Fundamentals) instructor just drops KinectColorViewer to a screen, sets path and it's working.
The KinectColorViewer available in the KinectWpfViewers assembly is used in the "Kinect Explorer" example, and that is the best place to see how it is used and behaves. From this example you will find that the proper way to initialize the viewer in the XAML and the bindings that are necessary.
From the code you posted, you appear to binding the Kinect itself (a reference to the hardware) to the KinectColorViewer, which is not what it is expecting. You need to be setting a reference to a KinectSensorManager class, which is part of the KinectWpfViewers assembly.
Here is a simplified XAML with a KinectColorViewer
<Window x:Class="Microsoft.Samples.Kinect.KinectExplorer.KinectWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Microsoft.Samples.Kinect.KinectExplorer"
xmlns:kt="clr-namespace:Microsoft.Samples.Kinect.WpfViewers;assembly=Microsoft.Samples.Kinect.WpfViewers"
Title="Kinect Explorer" Width="812" Height="768">
<Grid>
<kt:KinectColorViewer x:Name="ColorViewer" KinectSensorManager="{Binding KinectSensorManager}" CollectFrameRate="True" RetainImageOnSensorChange="True" />
</Grid>
</Window>
Then you XAML.CS constructor will look something similar to:
public KinectWindow()
{
this.viewModel = new KinectWindowViewModel();
// The KinectSensorManager class is a wrapper for a KinectSensor that adds
// state logic and property change/binding/etc support, and is the data model
// for KinectDiagnosticViewer.
this.viewModel.KinectSensorManager = new KinectSensorManager();
Binding sensorBinding = new Binding("KinectSensor");
sensorBinding.Source = this;
BindingOperations.SetBinding(this.viewModel.KinectSensorManager, KinectSensorManager.KinectSensorProperty, sensorBinding);
// Attempt to turn on Skeleton Tracking for each Kinect Sensor
this.viewModel.KinectSensorManager.SkeletonStreamEnabled = true;
this.DataContext = this.viewModel;
InitializeComponent();
}
Review the "Kinect Explorer" example for complete details.
I had the same problem with using KinectSensorManager. It turns out you need to call to Microsoft.Samples.Kinect.Wpf.Viewers and not just the kinect.dll, kinect.toolkit.dll, and kinect.controls.dll.
However, when I implemented KinectSensorManager, then the KinectUI and SensorChooser stopped working on my xaml interface.

Categories