GIF animation CPU consumption problem in C#! - c#

I have made a GIF Animation user control which loads gif animations and have created about 30 of them in my project each animating a GIF. The problem is that when I check my CPU usage it is about 70%+!!! I'm sure something is wrong with this!
Please help me. Here is the code of that GIF Animator control:
public class AnimatedImage : System.Windows.Controls.Image
{
private BitmapSource[] _BitmapSources = null;
private int _nCurrentFrame=0;
private bool _bIsAnimating=false;
public bool IsAnimating
{
get { return _bIsAnimating; }
}
static AnimatedImage()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(AnimatedImage), new FrameworkPropertyMetadata(typeof(AnimatedImage)));
}
public Bitmap AnimatedBitmap
{
get { return (Bitmap)GetValue(AnimatedBitmapProperty); }
set { StopAnimate(); SetValue(AnimatedBitmapProperty, value); }
}
/// <summary>
/// Identifies the Value dependency property.
/// </summary>
public static readonly DependencyProperty AnimatedBitmapProperty =
DependencyProperty.Register(
"AnimatedBitmap", typeof(Bitmap), typeof(AnimatedImage),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnAnimatedBitmapChanged)));
private static void OnAnimatedBitmapChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
AnimatedImage control = (AnimatedImage)obj;
control.UpdateAnimatedBitmap();
RoutedPropertyChangedEventArgs<Bitmap> e = new RoutedPropertyChangedEventArgs<Bitmap>(
(Bitmap)args.OldValue, (Bitmap)args.NewValue, AnimatedBitmapChangedEvent);
control.OnAnimatedBitmapChanged(e);
}
/// <summary>
/// Identifies the ValueChanged routed event.
/// </summary>
public static readonly RoutedEvent AnimatedBitmapChangedEvent = EventManager.RegisterRoutedEvent(
"AnimatedBitmapChanged", RoutingStrategy.Bubble,
typeof(RoutedPropertyChangedEventHandler<Bitmap>), typeof(AnimatedImage));
/// <summary>
/// Occurs when the Value property changes.
/// </summary>
public event RoutedPropertyChangedEventHandler<Bitmap> AnimatedBitmapChanged
{
add { AddHandler(AnimatedBitmapChangedEvent, value); }
remove { RemoveHandler(AnimatedBitmapChangedEvent, value); }
}
/// <summary>
/// Raises the ValueChanged event.
/// </summary>
/// <param name="args">Arguments associated with the ValueChanged event.</param>
protected virtual void OnAnimatedBitmapChanged(RoutedPropertyChangedEventArgs<Bitmap> args)
{
RaiseEvent(args);
}
private void UpdateAnimatedBitmap()
{
int nTimeFrames = AnimatedBitmap.GetFrameCount(System.Drawing.Imaging.FrameDimension.Time);
_nCurrentFrame = 0;
if (nTimeFrames > 0)
{
_BitmapSources = new BitmapSource[nTimeFrames];
for (int i = 0; i < nTimeFrames; i++)
{
AnimatedBitmap.SelectActiveFrame(System.Drawing.Imaging.FrameDimension.Time, i);
Bitmap bitmap = new Bitmap(AnimatedBitmap);
bitmap.MakeTransparent();
_BitmapSources[i] = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bitmap.GetHbitmap(),
IntPtr.Zero,
Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
}
StartAnimate();
}
}
private delegate void VoidDelegate();
private void OnFrameChanged(object o, EventArgs e)
{
Dispatcher.BeginInvoke(DispatcherPriority.Render, new VoidDelegate(delegate { ChangeSource(); }));
}
void ChangeSource()
{
Source = _BitmapSources[_nCurrentFrame++];
_nCurrentFrame = _nCurrentFrame % _BitmapSources.Length;
ImageAnimator.UpdateFrames();
}
public void StopAnimate()
{
if (_bIsAnimating)
{
ImageAnimator.StopAnimate(AnimatedBitmap, new EventHandler(this.OnFrameChanged));
_bIsAnimating = false;
}
}
public void StartAnimate()
{
if (!_bIsAnimating)
{
ImageAnimator.Animate(AnimatedBitmap, new EventHandler(this.OnFrameChanged));
_bIsAnimating = true;
}
}
}
}

Give this one a shot. We've used it in our application and I haven't notice any weird memory consumption.

Related

how can I return value from show dialog form?

The main form:
fDocForm fDocForm = new fDocForm()
fDocForm.ShowDialog();
if(fDocForm.DialogResult!=null)
//use of id returned from dialog form
else
MessageBox.Show("null");
in the dialog form:
private void button1_Click(object sender, EventArgs e)
{
//insert sql command and returned id of inserted recored
DialogResult = DialogResult.OK;
this.Hide();
}
how could I return the id value from the dialog form to the main form?
One option is to pass data from child form to parent form using an event which is invoked when clicking a button on the child form, data is in a validate state invoke the event then set DialogResult to OK.
The following is a conceptual example where the main form opens a child form for adding a new item of type Note.
If all you need is a single property/value this will still work by changing the delegate signature OnAddNote.
Note class
public class Note : INotifyPropertyChanged
{
private string _title;
private string _content;
private int _id;
public int Id
{
get => _id;
set
{
_id = value;
OnPropertyChanged();
}
}
public string Title
{
get => _title;
set
{
_title = value;
OnPropertyChanged();
}
}
public string Content
{
get => _content;
set
{
_content = value;
OnPropertyChanged();
}
}
public override string ToString() => Title;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Operations class
NewNote method is called from the child form Add button when data is validated
public class Operations
{
public delegate void OnAddNote(Note note);
public static event OnAddNote AddNote;
public static List<Note> NotesList = new List<Note>();
/// <summary>
/// Pass new Note to listeners
/// </summary>
/// <param name="note"></param>
public static void NewNote(Note note)
{
AddNote?.Invoke(note);
}
/// <summary>
/// Edit note, do some validation
/// </summary>
/// <param name="note"></param>
/// <returns></returns>
public static Note EditNote(Note note)
{
throw new NotImplementedException();
}
/// <summary>
/// Load mocked data, for a real application if persisting data use <see cref="LoadNotes"/>
/// </summary>
public static void Mocked()
{
NotesList.Add(new Note()
{
Title = "First",
Content = "My note"
});
}
/// <summary>
/// For a real application which persist your notes we would load from
/// - a database
/// - file (xml, json etc)
/// </summary>
/// <returns></returns>
public static List<Note> LoadNotes()
{
throw new NotImplementedException();
}
/// <summary>
/// Delete a note in <see cref="NotesList"/>
/// </summary>
/// <param name="note"></param>
public static void Delete(Note note)
{
throw new NotImplementedException();
}
public static Note FindByTitle(string title)
{
throw new NotImplementedException();
}
/// <summary>
/// Save data to the data source loaded from <see cref="LoadNotes"/>
/// </summary>
/// <returns>
/// Named value tuple
/// success - operation was successful
/// exception - if failed what was the cause
/// </returns>
public static (bool success, Exception exception) Save()
{
throw new NotImplementedException();
}
}
Child form
public partial class AddNoteForm : Form
{
public AddNoteForm()
{
InitializeComponent();
}
private void AddButton_Click(object sender, EventArgs e)
{
if (!string.IsNullOrWhiteSpace(TitleTextBox.Text) && !string.IsNullOrWhiteSpace(NoteTextBox.Text))
{
Operations.NewNote(new Note() {Title = TitleTextBox.Text, Content = NoteTextBox.Text});
DialogResult = DialogResult.OK;
}
else
{
DialogResult = DialogResult.Cancel;
}
}
}
Main form
public partial class Form1 : Form
{
private readonly BindingSource _bindingSource = new BindingSource();
public Form1()
{
InitializeComponent();
Shown += OnShown;
}
private void OnShown(object sender, EventArgs e)
{
Operations.AddNote += OperationsOnAddNote;
Operations.Mocked();
_bindingSource.DataSource = Operations.NotesList;
NotesListBox.DataSource = _bindingSource;
ContentsTextBox.DataBindings.Add("Text", _bindingSource, "Content");
}
private void OperationsOnAddNote(Note note)
{
_bindingSource.Add(note);
NotesListBox.SelectedIndex = NotesListBox.Items.Count - 1;
}
private void AddButton_Click(object sender, EventArgs e)
{
var addForm = new AddNoteForm();
try
{
addForm.ShowDialog();
}
finally
{
addForm.Dispose();
}
}
}
Full source
You can store the id in a public property of the dialog, and the access that property from the main form.

How to add data to the list when "pull to refresh" without clearing old data

I have a PulltoRefreshListView control:
public class PullToRefreshListView : ListView
{
private const string ScrollViewerControl = "ScrollViewer";
private const string ContainerGrid = "ContainerGrid";
private const string PullToRefreshIndicator = "PullToRefreshIndicator";
private const string RefreshButton = "RefreshButton";
private const string VisualStateNormal = "Normal";
private const string VisualStateReadyToRefresh = "ReadyToRefresh";
private DispatcherTimer compressionTimer;
private ScrollViewer scrollViewer;
private DispatcherTimer timer;
private Grid containerGrid;
private Border pullToRefreshIndicator;
private bool isCompressionTimerRunning;
private bool isReadyToRefresh;
private bool isCompressedEnough;
public event EventHandler RefreshContent;
public static readonly DependencyProperty PullTextProperty = DependencyProperty.Register("PullText", typeof(string), typeof(PullToRefreshListView), new PropertyMetadata("Pull to refresh"));
public static readonly DependencyProperty RefreshTextProperty = DependencyProperty.Register("RefreshText", typeof(string), typeof(PullToRefreshListView), new PropertyMetadata("Release to refresh"));
public static readonly DependencyProperty RefreshHeaderHeightProperty = DependencyProperty.Register("RefreshHeaderHeight", typeof(double), typeof(PullToRefreshListView), new PropertyMetadata(40D));
public static readonly DependencyProperty RefreshCommandProperty = DependencyProperty.Register("RefreshCommand", typeof(ICommand), typeof(PullToRefreshListView), new PropertyMetadata(null));
public static readonly DependencyProperty ArrowColorProperty = DependencyProperty.Register("ArrowColor", typeof(Brush), typeof(PullToRefreshListView), new PropertyMetadata(new SolidColorBrush(Colors.Red)));
private double offsetTreshhold = 40;
public PullToRefreshListView()
{
this.DefaultStyleKey = typeof(PullToRefreshListView);
Loaded += PullToRefreshScrollViewer_Loaded;
this.SizeChanged += PullToRefreshListView_SizeChanged;
}
private void PullToRefreshListView_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (ItemsPanelRoot != null)
ItemsPanelRoot.Width = e.NewSize.Width;
}
public ICommand RefreshCommand
{
get { return (ICommand)GetValue(RefreshCommandProperty); }
set { SetValue(RefreshCommandProperty, value); }
}
public double RefreshHeaderHeight
{
get { return (double)GetValue(RefreshHeaderHeightProperty); }
set { SetValue(RefreshHeaderHeightProperty, value); }
}
public string RefreshText
{
get { return (string)GetValue(RefreshTextProperty); }
set { SetValue(RefreshTextProperty, value); }
}
public string PullText
{
get { return (string)GetValue(PullTextProperty); }
set { SetValue(PullTextProperty, value); }
}
public Brush ArrowColor
{
get { return (Brush)GetValue(ArrowColorProperty); }
set { SetValue(ArrowColorProperty, value); }
}
protected override void OnApplyTemplate()
{
try
{
base.OnApplyTemplate();
scrollViewer = (ScrollViewer)GetTemplateChild(ScrollViewerControl);
scrollViewer.ViewChanging += ScrollViewer_ViewChanging;
scrollViewer.Margin = new Thickness(0, 0, 0, -RefreshHeaderHeight);
var transform = new CompositeTransform();
transform.TranslateY = -RefreshHeaderHeight;
scrollViewer.RenderTransform = transform;
containerGrid = (Grid)GetTemplateChild(ContainerGrid);
pullToRefreshIndicator = (Border)GetTemplateChild(PullToRefreshIndicator);
SizeChanged += OnSizeChanged;
}
catch (Exception wd)
{
var dwd = wd.Message;
}
}
/// <summary>
/// Initiate timers to detect if we're scrolling into negative space
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PullToRefreshScrollViewer_Loaded(object sender, RoutedEventArgs e)
{
// Show Refresh Button on non-touch device.
if (new Windows.Devices.Input.TouchCapabilities().TouchPresent == 0)
{
var refreshButton = (Button)GetTemplateChild(RefreshButton);
refreshButton.Visibility = Visibility.Visible;
refreshButton.Click += RefreshButton_Click;
}
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(100);
timer.Tick += Timer_Tick;
compressionTimer = new DispatcherTimer();
compressionTimer.Interval = TimeSpan.FromSeconds(.5);
compressionTimer.Tick += CompressionTimer_Tick;
timer.Start();
}
/// <summary>
/// Clip the bounds of the control to avoid showing the pull to refresh text
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnSizeChanged(object sender, SizeChangedEventArgs e)
{
Clip = new RectangleGeometry()
{
Rect = new Rect(0, 0, e.NewSize.Width, e.NewSize.Height)
};
}
/// <summary>
/// Detect if we've scrolled all the way to the top. Stop timers when we're not completely in the top
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ScrollViewer_ViewChanging(object sender, ScrollViewerViewChangingEventArgs e)
{
if (e.NextView.VerticalOffset == 0)
{
timer.Start();
}
else
{
if (timer != null)
{
timer.Stop();
}
if (compressionTimer != null)
{
compressionTimer.Stop();
}
isCompressionTimerRunning = false;
isCompressedEnough = false;
isReadyToRefresh = false;
VisualStateManager.GoToState(this, VisualStateNormal, true);
}
}
/// <summary>
/// Detect if I've scrolled far enough and been there for enough time to refresh
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CompressionTimer_Tick(object sender, object e)
{
if (isCompressedEnough)
{
VisualStateManager.GoToState(this, VisualStateReadyToRefresh, true);
isReadyToRefresh = true;
}
else
{
isCompressedEnough = false;
compressionTimer.Stop();
}
}
/// <summary>
/// Invoke timer if we've scrolled far enough up into negative space. If we get back to offset 0 the refresh command and event is invoked.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Timer_Tick(object sender, object e)
{
if (containerGrid != null)
{
Rect elementBounds = pullToRefreshIndicator.TransformToVisual(containerGrid).TransformBounds(new Rect(0.0, 0.0, pullToRefreshIndicator.Height, RefreshHeaderHeight));
var compressionOffset = elementBounds.Bottom;
if (compressionOffset > offsetTreshhold)
{
if (isCompressionTimerRunning == false)
{
isCompressionTimerRunning = true;
compressionTimer.Start();
}
isCompressedEnough = true;
}
else if (compressionOffset == 0 && isReadyToRefresh == true)
{
InvokeRefresh();
}
else
{
isCompressedEnough = false;
isCompressionTimerRunning = false;
}
}
}
private void RefreshButton_Click(object sender, object e)
{
InvokeRefresh();
}
/// <summary>
/// Set correct visual state and invoke refresh event and command
/// </summary>
private void InvokeRefresh()
{
isReadyToRefresh = false;
VisualStateManager.GoToState(this, VisualStateNormal, true);
if (RefreshContent != null)
{
RefreshContent(this, EventArgs.Empty);
}
if (RefreshCommand != null && RefreshCommand.CanExecute(null) == true)
{
RefreshCommand.Execute(null);
}
}
}
and i use it in xaml:
<controls:PullToRefreshListView ItemsSource="{Binding TrackListItems}"
RefreshCommand="{Binding RefreshCommand}">
</controls:PullToRefreshListView>
and code behind:
refreshCommand = new RelayCommandN(RefreshItems);
public void RefreshItems()
{
TrackListItems.Clear();
//code: added my data in List: TrackListItems
}
In this way I always have new data, but the sheet is cleaned completely. How to do to the old data remain, and only add new data to the top of the list after "Pull To Refresh"?
What is the right strategy? I can find the data are marked as new. How to add them to the top of the list? And that there is no glitches? And do not clear the all list?
You can use List.Insert(0, newItem) to add items to the top of the list. If you want to add multiple items, you'll call have to use it multiple times. Note that calling Insert with 0 adds the items to the top of the list, which works if your items are in reverse order. If you want to add them in order, you can do something like this:
public void Refresh(ObservableCollection<Item> myList, List<Item> newItems)
{
for(int i = 0; i < newItems.Count; i++)
{
myList.Insert(i, newItem=newItems[i]);
}
}

xbox 360 kinect beam angle issue with property change

trying to get the beam angle in a C# wpf and there is an exception being thrown on the If PropertyChange. Does anyone have an example of this project, I can supply more information if needed. I am trying to get the mics change the property but instead it is throwing an exception
InitializeComponent();
//Beam Angle Code
this.DataContext = this.Rect;
this.Loaded += delegate { ListenForBeamChanges(); };
}
private KinectAudioSource CreateAudioSource()
{
var source = KinectSensor.KinectSensors[0].AudioSource;
source.NoiseSuppression = true;
source.AutomaticGainControlEnabled = true;
source.BeamAngleMode = BeamAngleMode.Adaptive;
return source;
}
private KinectAudioSource audioSource;
private void ListenForBeamChanges()
{
KinectSensor.KinectSensors[0].Start();
audioSource = CreateAudioSource();
audioSource.BeamAngleChanged += audioSource_BeamChanged;
audioSource.Start();
}
public double _beamAngle;
public double BeamAngle
{
get { return _beamAngle; }
set
{
_beamAngle = value;
OnPropertyChanged("BeamAngle");
}
}
void audioSource_BeamChanged(object sender, BeamAngleChangedEventArgs e)
{
BeamAngle = e.Angle * -1;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}
see http://kinectaudioposition.codeplex.com
copying sample usage code from http://channel9.msdn.com/coding4fun/kinect/Kinect-Audio-Positioning
/// <summary>
/// Event handler to care Window loaded
/// Construct KinectMicArray and draw contents
/// </summary>
private void Window_Loaded(object sender, RoutedEventArgs e)
{
kinectMic = new KinectMicArray();
kinectMic.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(kinectMic_PropertyChanged);
DrawContents();
}
/// <summary>
/// Event handler to care KinectMicArray property changed
/// Showing angles as number for debug
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void kinectMic_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
KinectMicArray ka = sender as KinectMicArray;
this.myLabel.Content = string.Format("Beam = {0:F}; Source = {1:F}; ", ka.BeamAngleProperty, ka.SourceAngleProperty);
}

Flash Light Using Video Camera

I found on the internet a tutorial (http://www.locked.nl) to turn Flash light on permanently. In the StartRecording() Method I am getting an exception when calling the Method twice. Also, How can I stop the recording ?? Thank you so much
I had these 2 classes.
VideoCamera Class:
public class VideoCamera
{
private object _videoCamera;
private PropertyInfo _videoCameraLampEnabledPropertyInfo;
private MethodInfo _videoCameraStartRecordingMethod;
private MethodInfo _videoCameraStopRecordingMethod;
private EventHandler _videoCameraInitialized;
public object InnerCameraObject
{
get { return _videoCamera; }
}
public bool LampEnabled
{
get { return (bool)_videoCameraLampEnabledPropertyInfo.GetGetMethod().Invoke(_videoCamera, new object[0]); }
set { _videoCameraLampEnabledPropertyInfo.GetSetMethod().Invoke(_videoCamera, new object[] { value }); }
}
public VideoCamera()
{
// Load the media extended assembly which contains the extended video camera object.
Assembly mediaExtendedAssembly = Assembly.Load("Microsoft.Phone.Media.Extended, Version=7.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e");
// Get the camera source type (primary camera).
Type cameraSourceType = mediaExtendedAssembly.GetType("Microsoft.Phone.CameraSource");
FieldInfo field = cameraSourceType.GetField("PrimaryCamera");
object cameraSource = Enum.ToObject(cameraSourceType, (int)field.GetValue(cameraSourceType));
// Create the video camera object.
Type videoCameraType = mediaExtendedAssembly.GetType("Microsoft.Phone.VideoCamera");
ConstructorInfo videoCameraConstructor = videoCameraType.GetConstructor(new Type[] { cameraSourceType });
_videoCamera = videoCameraConstructor.Invoke(new object[] { cameraSource });
// Set the properties and methods.
_videoCameraLampEnabledPropertyInfo = videoCameraType.GetProperty("LampEnabled");
_videoCameraStartRecordingMethod = videoCameraType.GetMethod("StartRecording");
_videoCameraStopRecordingMethod = videoCameraType.GetMethod("StopRecording");
// Let the initialize event bubble through.
_videoCameraInitialized = new EventHandler(VideoCamera_Initialized);
MethodInfo addInitializedEventMethodInfo = videoCameraType.GetMethod("add_Initialized");
addInitializedEventMethodInfo.Invoke(_videoCamera, new object[] { _videoCameraInitialized });
}
/// <summary>
/// Occurs when the camera object has been initialized.
/// </summary>
public event EventHandler Initialized;
/// <summary>
/// Videoes the camera_ initialized.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="eventArgs">The event args.</param>
private void VideoCamera_Initialized(object sender, object eventArgs)
{
if (Initialized != null)
{
Initialized.Invoke(this, new EventArgs());
}
}
public bool IsRecording { get; private set; }
/// <summary>
/// Start recording.
/// </summary>
public void StartRecording()
{
_videoCameraStartRecordingMethod.Invoke(_videoCamera, new object[0]);
}
public void StopRecording()
{
}
}
}
and this class VideoCameraVisualizer
public class VideoCameraVisualizer : UserControl
{
private object _cameraVisualizer;
private MethodInfo _cameraVisualizerSetSourceMethod;
public VideoCameraVisualizer()
{
// Load the media extended assembly which contains the extended video camera object.
Assembly mediaExtendedAssembly = Assembly.Load("Microsoft.Phone.Media.Extended, Version=7.0.0.0, Culture=neutral, PublicKeyToken=24eec0d8c86cda1e");
// Get the camera source type (primary camera).
Type cameraVisualizerType = mediaExtendedAssembly.GetType("Microsoft.Phone.CameraVisualizer");
ConstructorInfo cameraVisualizerConstructor = cameraVisualizerType.GetConstructor(Type.EmptyTypes);
_cameraVisualizer = cameraVisualizerConstructor.Invoke(null);
// Set the properties and methods.
_cameraVisualizerSetSourceMethod = cameraVisualizerType.GetMethod("SetSource");
}
public void SetSource(VideoCamera camera)
{
// Invoke the set source method on the camera visualizer object.
_cameraVisualizerSetSourceMethod.Invoke(_cameraVisualizer, new object[] { camera.InnerCameraObject });
}
}
}
Now in the MainPage I had this Code that is giving an error.
private void ContentPanel_Loaded(object sender, RoutedEventArgs e)
{
// Check to see if the camera is available on the device.
if (PhotoCamera.IsCameraTypeSupported(CameraType.Primary))
{
// Use standard camera on back of device.
videoCam = new VideoCamera();
// Event is fired when the video camera object has been initialized.
videoCam.Initialized += VideoCamera_Initialized;
// Add the photo camera to the video source
CameraVisualizer = new VideoCameraVisualizer();
CameraVisualizer.SetSource(videoCam);
}
else MessageBox.Show("No Flash supported for Your Device. Try Color Button");
}
private void VideoCamera_Initialized(object sender, EventArgs e)
{
videoCam.LampEnabled = true;
videoCam.StartRecording();
count++;
}
private void FlashButton_Click(object sender, RoutedEventArgs e)
{
if (count % 2 == 0)
{
videoCam.LampEnabled = true;
videoCam.StartRecording();
}
else
{
videoCam.LampEnabled = false;
videoCam.StopRecording();
}
count++;
}
}
}
Improve your google skills! ;)
have a read of this SO post - How to stop led torch/flashlight app using Reflection in Windows Phone 7
P.S. This is a nice blog post about the subject Using Cameras in Your Windows Phone Application

AutoSuggestion in a WPF combobox

My combobox returns a set of values from s stored procedure as this
private void BindCombo()
{
DataCombo.FillCombo(ComboDS(2313001), cmbClass, 0);
DataCombo.FillCombo(DDCombo(5007), cmbGroup, 0);
}
I managed to give a rudimentary auto complete suggestion as IsTextSearchenabled but cannot get a auto suggestion box that i would like.
I have seen loads of examples of autocomplete/suggestive textboxes but none of them seem to suit me.
this code apparently suits me.
but how would i use the auto suggest here
using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace DotNetZen.AutoFilteredComboBox
{
public class AutoFilteredComboBox : ComboBox
{
private int silenceEvents = 0;
/// <summary>
/// Creates a new instance of <see cref="AutoFilteredComboBox" />.
/// </summary>
public AutoFilteredComboBox()
{
DependencyPropertyDescriptor textProperty = DependencyPropertyDescriptor.FromProperty(
ComboBox.TextProperty, typeof(AutoFilteredComboBox));
textProperty.AddValueChanged(this, this.OnTextChanged);
this.RegisterIsCaseSensitiveChangeNotification();
}
#region IsCaseSensitive Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="IsCaseSensitive" /> dependency property.
/// </summary>
public static readonly DependencyProperty IsCaseSensitiveProperty =
DependencyProperty.Register("IsCaseSensitive", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(false));
/// <summary>
/// Gets or sets the way the combo box treats the case sensitivity of typed text.
/// </summary>
/// <value>The way the combo box treats the case sensitivity of typed text.</value>
[System.ComponentModel.Description("The way the combo box treats the case sensitivity of typed text.")]
[System.ComponentModel.Category("AutoFiltered ComboBox")]
[System.ComponentModel.DefaultValue(true)]
public bool IsCaseSensitive
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(IsCaseSensitiveProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(IsCaseSensitiveProperty, value);
}
}
protected virtual void OnIsCaseSensitiveChanged(object sender, EventArgs e)
{
if (this.IsCaseSensitive)
this.IsTextSearchEnabled = false;
this.RefreshFilter();
}
private void RegisterIsCaseSensitiveChangeNotification()
{
System.ComponentModel.DependencyPropertyDescriptor.FromProperty(IsCaseSensitiveProperty, typeof(AutoFilteredComboBox)).AddValueChanged(
this, this.OnIsCaseSensitiveChanged);
}
#endregion
#region DropDownOnFocus Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="DropDownOnFocus" /> dependency property.
/// </summary>
public static readonly DependencyProperty DropDownOnFocusProperty =
DependencyProperty.Register("DropDownOnFocus", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(true));
/// <summary>
/// Gets or sets the way the combo box behaves when it receives focus.
/// </summary>
/// <value>The way the combo box behaves when it receives focus.</value>
[System.ComponentModel.Description("The way the combo box behaves when it receives focus.")]
[System.ComponentModel.Category("AutoFiltered ComboBox")]
[System.ComponentModel.DefaultValue(true)]
public bool DropDownOnFocus
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(DropDownOnFocusProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(DropDownOnFocusProperty, value);
}
}
#endregion
#region | Handle selection |
/// <summary>
/// Called when <see cref="ComboBox.ApplyTemplate()"/> is called.
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.EditableTextBox.SelectionChanged += this.EditableTextBox_SelectionChanged;
}
/// <summary>
/// Gets the text box in charge of the editable portion of the combo box.
/// </summary>
protected TextBox EditableTextBox
{
get
{
return ((TextBox)base.GetTemplateChild("PART_EditableTextBox"));
}
}
private int start = 0, length = 0;
private void EditableTextBox_SelectionChanged(object sender, RoutedEventArgs e)
{
if (this.silenceEvents == 0)
{
this.start = ((TextBox)(e.OriginalSource)).SelectionStart;
this.length = ((TextBox)(e.OriginalSource)).SelectionLength;
this.RefreshFilter();
}
}
#endregion
#region | Handle focus |
/// <summary>
/// Invoked whenever an unhandled <see cref="UIElement.GotFocus" /> event
/// reaches this element in its route.
/// </summary>
/// <param name="e">The <see cref="RoutedEventArgs" /> that contains the event data.</param>
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
if (this.ItemsSource != null && this.DropDownOnFocus)
{
this.IsDropDownOpen = true;
}
}
#endregion
#region | Handle filtering |
private void RefreshFilter()
{
if (this.ItemsSource != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(this.ItemsSource);
view.Refresh();
this.IsDropDownOpen = true;
}
}
private bool FilterPredicate(object value)
{
// We don't like nulls.
if (value == null)
return false;
// If there is no text, there's no reason to filter.
if (this.Text.Length == 0)
return true;
string prefix = this.Text;
// If the end of the text is selected, do not mind it.
if (this.length > 0 && this.start + this.length == this.Text.Length)
{
prefix = prefix.Substring(0, this.start);
}
return value.ToString()
.StartsWith(prefix, !this.IsCaseSensitive, CultureInfo.CurrentCulture);
}
#endregion
/// <summary>
/// Called when the source of an item in a selector changes.
/// </summary>
/// <param name="oldValue">Old value of the source.</param>
/// <param name="newValue">New value of the source.</param>
protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue)
{
if (newValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(newValue);
view.Filter += this.FilterPredicate;
}
if (oldValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(oldValue);
view.Filter -= this.FilterPredicate;
}
base.OnItemsSourceChanged(oldValue, newValue);
}
private void OnTextChanged(object sender, EventArgs e)
{
if (!this.IsTextSearchEnabled && this.silenceEvents == 0)
{
this.RefreshFilter();
// Manually simulate the automatic selection that would have been
// available if the IsTextSearchEnabled dependency property was set.
if (this.Text.Length > 0)
{
foreach (object item in CollectionViewSource.GetDefaultView(this.ItemsSource))
{
int text = item.ToString().Length, prefix = this.Text.Length;
this.SelectedItem = item;
this.silenceEvents++;
this.EditableTextBox.Text = item.ToString();
this.EditableTextBox.Select(prefix, text - prefix);
this.silenceEvents--;
break;
}
}
}
}
}
}
Also found the AutoFilteredComboBox to be very simple to work with. Though I have made some changes:
Removed use of DependencyPropertyDescriptor to avoid memory leak of combobox-objects
Introduced FilterItem-event and FilterList-event to allow one to customize the filtering
Changed default filtering from starts-with-string to contains-string
Removed support of having IsTextSearchEnabled enabled
Shows dropdown as soon one changes the search string, so search result is displayed
Example of how it is used:
<Controls:AutoFilteredComboBox ItemsSource="{Binding ViewModel.AvailableItems}"
SelectedValue="{Binding ViewModel.SelectedItem, Mode=TwoWay}"
IsEditable="True" IsTextSearchEnabled="False"/>
Improved version of AutoFilteredComboBox:
public class AutoFilteredComboBox : ComboBox
{
bool _ignoreTextChanged;
string _currentText;
/// <summary>
/// Creates a new instance of <see cref="AutoFilteredComboBox" />.
/// </summary>
public AutoFilteredComboBox()
{
if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) return;
}
public event Func<object, string, bool> FilterItem;
public event Action<string> FilterList;
#region IsCaseSensitive Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="IsCaseSensitive" /> dependency property.
/// </summary>
public static readonly DependencyProperty IsCaseSensitiveProperty =
DependencyProperty.Register("IsCaseSensitive", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(false));
/// <summary>
/// Gets or sets the way the combo box treats the case sensitivity of typed text.
/// </summary>
/// <value>The way the combo box treats the case sensitivity of typed text.</value>
[Description("The way the combo box treats the case sensitivity of typed text.")]
[Category("AutoFiltered ComboBox")]
[DefaultValue(true)]
public bool IsCaseSensitive
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(IsCaseSensitiveProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(IsCaseSensitiveProperty, value);
}
}
#endregion
#region DropDownOnFocus Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="DropDownOnFocus" /> dependency property.
/// </summary>
public static readonly DependencyProperty DropDownOnFocusProperty =
DependencyProperty.Register("DropDownOnFocus", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(false));
/// <summary>
/// Gets or sets the way the combo box behaves when it receives focus.
/// </summary>
/// <value>The way the combo box behaves when it receives focus.</value>
[Description("The way the combo box behaves when it receives focus.")]
[Category("AutoFiltered ComboBox")]
[DefaultValue(false)]
public bool DropDownOnFocus
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(DropDownOnFocusProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(DropDownOnFocusProperty, value);
}
}
#endregion
#region | Handle focus |
/// <summary>
/// Invoked whenever an unhandled <see cref="UIElement.GotFocus" /> event
/// reaches this element in its route.
/// </summary>
/// <param name="e">The <see cref="RoutedEventArgs" /> that contains the event data.</param>
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
if (this.ItemsSource != null && this.DropDownOnFocus)
{
this.IsDropDownOpen = true;
}
}
#endregion
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(OnTextChanged));
KeyUp += AutoFilteredComboBox_KeyUp;
this.IsTextSearchEnabled = false;
}
void AutoFilteredComboBox_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Down)
{
if (this.IsDropDownOpen == true)
{
// Ensure that focus is given to the dropdown list
if (Keyboard.FocusedElement is TextBox)
{
Keyboard.Focus(this);
if (this.Items.Count > 0)
{
if (this.SelectedIndex == -1 || this.SelectedIndex==0)
this.SelectedIndex = 0;
}
}
}
}
if (Keyboard.FocusedElement is TextBox)
{
if (e.OriginalSource is TextBox)
{
// Avoid the automatic selection of the first letter (As next letter will cause overwrite)
TextBox textBox = e.OriginalSource as TextBox;
if (textBox.Text.Length == 1 && textBox.SelectionLength == 1)
{
textBox.SelectionLength = 0;
textBox.SelectionStart = 1;
}
}
}
}
#region | Handle filtering |
private void RefreshFilter()
{
if (this.ItemsSource != null)
{
Action<string> filterList = FilterList;
if (filterList != null)
{
filterList(_currentText);
}
else
{
ICollectionView view = CollectionViewSource.GetDefaultView(this.ItemsSource);
view.Refresh();
}
this.SelectedIndex = -1; // Prepare so arrow down selects first
this.IsDropDownOpen = true;
}
}
private bool FilterPredicate(object value)
{
// We don't like nulls.
if (value == null)
return false;
// If there is no text, there's no reason to filter.
if (string.IsNullOrEmpty(_currentText))
return true;
Func<object, string, bool> filterItem = FilterItem;
if (filterItem != null)
return filterItem(value, _currentText);
if (IsCaseSensitive)
return value.ToString().Contains(_currentText);
else
return value.ToString().ToUpper().Contains(_currentText.ToUpper());
}
#endregion
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
try
{
_ignoreTextChanged = true; // Ignore the following TextChanged
base.OnSelectionChanged(e);
}
finally
{
_ignoreTextChanged = false;
}
}
/// <summary>
/// Called when the source of an item in a selector changes.
/// </summary>
/// <param name="oldValue">Old value of the source.</param>
/// <param name="newValue">New value of the source.</param>
protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
if (newValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(newValue);
if (FilterList == null)
view.Filter += this.FilterPredicate;
}
if (oldValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(oldValue);
view.Filter -= this.FilterPredicate;
}
base.OnItemsSourceChanged(oldValue, newValue);
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
if (_ignoreTextChanged)
return;
_currentText = Text;
if (!this.IsTextSearchEnabled)
{
this.RefreshFilter();
}
}
I have found a super simple workaround to my problem.
i created a preview text input event of the combobox.
then i just wrote
Combobox.IsDropDownOpen = true
may not the most elegant but works in my case

Categories