WPF c# SendKeys to another Windows - c#

I want to send Keys, from a WPF, to another Window (e.g. editor)
I found this Methode
public static class SendKeys
{
public static void Send(Key key)
{
if (Keyboard.PrimaryDevice != null)
{
if (Keyboard.PrimaryDevice.ActiveSource != null)
{
var e1 = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, Key.Down) { RoutedEvent = Keyboard.KeyDownEvent };
InputManager.Current.ProcessInput(e1);
}
}
}
}
, but it doesn't work :/
so I call it from my main program
SendKeys.Send(Key.D7);
In this case is WindowsForms not an alternative :/

Use the key parameter passed instead of Key.Down.
This worked fine:
public partial class MainWindow : Window
{
public MainWindow()
{
this.Loaded += OnLoaded;
this.KeyDown += OnKeyDown;
InitializeComponent();
}
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
SendKeys.Send(Key.A);
SendKeys.Send(Key.B);
SendKeys.Send(Key.C);
SendKeys.Send(Key.D);
SendKeys.Send(Key.LeftCtrl);
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show("Key pressed: " + e.Key);
}
}
public static class SendKeys
{
public static void Send(Key key)
{
if (Keyboard.PrimaryDevice != null)
{
if (Keyboard.PrimaryDevice.ActiveSource != null)
{
var e1 = new KeyEventArgs(Keyboard.PrimaryDevice, Keyboard.PrimaryDevice.ActiveSource, 0, key) { RoutedEvent = Keyboard.PreviewKeyDownEvent };
InputManager.Current.ProcessInput(e1);
}
}
}
}

Related

Cannot implicitly convert type 'bool' to System.Windows.Forms.RadioButton

public partial class Form2 : Form
{
public bool male {get; set;}
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
maleGender_rb1 = male;
}
}
I want to display the radio buttton result from form1 to form2 using also radio buttons
The best solution is to setup an event in the child form and for the RadioButton controls subscribe to CheckedChanged. The CheckedChange event determines which RadioButton was checked and sends notification to any listeners.
Child form:
namespace PassStringFromChildToParentForm
{
public partial class ChildForm : Form
{
public delegate void OnPassData(bool isMale);
public event OnPassData PassData;
public ChildForm()
{
InitializeComponent();
MaleRadioButton.Checked = true;
MaleRadioButton.CheckedChanged += RadioButton_CheckedChanged;
FemaleRadioButton.CheckedChanged += RadioButton_CheckedChanged;
}
private void RadioButton_CheckedChanged(object sender, EventArgs e)
{
var radioButton = (RadioButton)sender;
if (radioButton.Checked)
{
PassData?.Invoke(radioButton == MaleRadioButton);
}
}
public void UpdateRadioButton(bool isMale)
{
if (isMale)
{
MaleRadioButton.Checked = true;
}
else
{
FemaleRadioButton.Checked = true;
}
}
}
}
Main Form:
Here we subscribe to the child form event and determine which RadioButton to check based on the bool value passed.
namespace PassStringFromChildToParentForm
{
public partial class MainForm : Form
{
private ChildForm _childForm;
public MainForm()
{
InitializeComponent();
MaleRadioButton.CheckedChanged += RadioButton_CheckedChanged;
FemaleRadioButton.CheckedChanged += RadioButton_CheckedChanged;
}
private void RadioButton_CheckedChanged(object sender, EventArgs e)
{
if (Application.OpenForms.OfType<ChildForm>().Count() != 1) return;
var radioButton = (RadioButton)sender;
if (!radioButton.Checked) return;
if (!radioButton.Checked) return;
_childForm.UpdateRadioButton(MaleRadioButton.Checked);
}
private void ShowChildForm_Click(object sender, EventArgs e)
{
_childForm = new ChildForm();
_childForm.PassData += ChildForm_PassData; ;
_childForm.Show(this);
}
private void ChildForm_PassData(bool isMale)
{
if (isMale)
{
MaleRadioButton.Checked = true;
}
else
{
FemaleRadioButton.Checked = true;
}
}
}
}
You can't convert bool to RadioButton. I think you need to use Checked property of radio button to pass boolean value to it.
For example:
maleGender_rb1.Checked = true;// or false

Is in C# WPF apps a possibility to do something as long as a button is pressed?

I'm pretty new to C# and WPF, so please forgive me if my question maybe stupid. I come from the C++ world
I have an application that has a button, as long as I press the button I want to record a sounde from the microphone and when I release the button then the recording should stop. Just like the voice message in WhatsApps. I added the events PreviewMouseDown="ButtonLiveDown" and PreviewMouseUp="ButtonLiveUp" to my button and I can see that they are fired:
My main class:
m_MyLive = new AudioLive();
m_MyLive.Init(this);
private void ButtonLiveDown(object sender, MouseButtonEventArgs e)
{
m_MyLive.StartLive();
}
private void ButtonLiveUp(object sender, MouseButtonEventArgs e)
{
m_MyLive.EndLive();
}
and my Live Class:
class AudioLive
{
private MainWindow m_mainWindow;
private WaveIn m_Recorder;
private BufferedWaveProvider m_BufferedWaveProvider;
private SavingWaveProvider m_SavingWaveProvider;
private WaveOut m_Player;
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (m_Recorder != null)
{
m_Recorder.Dispose();
}
m_Recorder = null;
if (m_SavingWaveProvider != null)
{
m_SavingWaveProvider.Dispose();
}
m_SavingWaveProvider = null;
}
private void RecorderOnDataAvailable(object sender, WaveInEventArgs waveInEventArgs)
{
m_BufferedWaveProvider.AddSamples(waveInEventArgs.Buffer, 0, waveInEventArgs.BytesRecorded);
}
public bool Init(MainWindow mainWindow)
{
m_mainWindow = mainWindow;
m_Recorder = new WaveIn();
m_Recorder.DataAvailable += RecorderOnDataAvailable;
// set up our signal chain
m_BufferedWaveProvider = new BufferedWaveProvider(m_Recorder.WaveFormat);
m_SavingWaveProvider = new SavingWaveProvider(m_BufferedWaveProvider, "live.wav");
// set up playback
m_Player = new WaveOut();
m_Player.Init(m_SavingWaveProvider);
return true;
}
public void SetMicVolume(int nVol)
{
....
}
public void StartLive()
{
SetMicVolume(100);
// begin playback & record
m_Player.Play();
m_Recorder.StartRecording();
}
public void EndLive()
{
// stop recording
m_Recorder.StopRecording();
// stop playback
m_Player.Stop();
}
}
But this doesn't work, as long as I press the button down it seems that it stops working till I release the button. From C++ I know this, as long as I press the button the system is busy with the pressed Event and can't continue to work. Is it the same with C# & WPF? If yes, is there any other way to handle my feature wish?
If I understand your question, then yes, you will have to deal with UI blocking in this case. Use a background worker to kick the event on mouse down and background worker cancellation on mouse up. Example below shows with mouseup and mouse down event handelers as oppossed to the previewmouse up and down
Updated Example to help with understanding
XAML BUTTON:
<Button x:Name="RecordBtn" Content="Button" HorizontalAlignment="Left" Margin="363,199,0,0" VerticalAlignment="Top" Width="75" MouseDown="Button_MouseDown" MouseUp="Button_MouseUp"/>
xaml code behind showing background worker kicking and holding the process:
public partial class MainWindow : Window
{
private readonly BackgroundWorker worker = new BackgroundWorker();
AudioLive m_MyLive = new AudioLive();
Stopwatch stopWatch = new Stopwatch();
public MainWindow()
{
InitializeComponent();
AddHandler(FrameworkElement.MouseDownEvent, new MouseButtonEventHandler(Button_MouseDown), true);
AddHandler(FrameworkElement.MouseUpEvent, new MouseButtonEventHandler(Button_MouseUp), true);
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.WorkerSupportsCancellation = true;
m_MyLive.Init(this);
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
if (!m_MyLive.IsRecordinginProgress() && !worker.CancellationPending)
{
m_MyLive.StartLive();
stopWatch.Reset();
stopWatch.Start();
}
while (m_MyLive.IsRecordinginProgress() && !worker.CancellationPending)
{
this.Dispatcher.Invoke(() =>
{
updateLabel(String.Format("{0:0.#}", TimeSpan.FromMilliseconds(stopWatch.ElapsedMilliseconds).TotalSeconds) + " seconds");
});
}
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
m_MyLive.EndLive();
stopWatch.Stop();
updateLabel(String.Format("{0:0.#}", TimeSpan.FromMilliseconds(stopWatch.ElapsedMilliseconds).TotalSeconds) + " seconds");
}
private void updateLabel(string text)
{
RecordBtn.Content = text;
}
private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
worker.RunWorkerAsync();
}
private void Button_MouseUp(object sender, MouseButtonEventArgs e)
{
worker.CancelAsync();
}
}
Updated AudioLive to add property isRecording to use in our background worker:
public class AudioLive
{
private MainWindow m_mainWindow;
private WaveIn m_Recorder;
private BufferedWaveProvider m_BufferedWaveProvider;
private SavingWaveProvider m_SavingWaveProvider;
private WaveOut m_Player;
private bool isRecording { get; set; }
public bool IsRecordinginProgress()
{
return isRecording;
}
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (m_Recorder != null)
{
m_Recorder.Dispose();
}
m_Recorder = null;
if (m_SavingWaveProvider != null)
{
m_SavingWaveProvider.Dispose();
}
m_SavingWaveProvider = null;
}
private void RecorderOnDataAvailable(object sender, WaveInEventArgs waveInEventArgs)
{
m_BufferedWaveProvider.AddSamples(waveInEventArgs.Buffer, 0, waveInEventArgs.BytesRecorded);
}
public bool Init(MainWindow mainWindow)
{
m_mainWindow = mainWindow;
m_Recorder = new WaveIn();
m_Recorder.DataAvailable += RecorderOnDataAvailable;
// set up our signal chain
m_BufferedWaveProvider = new BufferedWaveProvider(m_Recorder.WaveFormat);
m_SavingWaveProvider = new SavingWaveProvider(m_BufferedWaveProvider, "live.wav");
// set up playback
m_Player = new WaveOut();
m_Player.Init(m_SavingWaveProvider);
return true;
}
public void SetMicVolume(int nVol)
{
}
public void StartLive()
{
SetMicVolume(100);
// begin playback & record
m_Player.Play();
m_Recorder.StartRecording();
isRecording = true;
}
public void EndLive()
{
// stop recording
m_Recorder.StopRecording();
// stop playback
m_Player.Stop();
isRecording = false;
}
}

C# UserControl Button click adds items to listbox from form1

I'm working on a C# app,that searches for song names on youtube (using youtube api) and displaying the data, I have a custom SongItem (UserControl) and I add them to a FlowLayoutControl. I added a "Favourite" button to the UserControl, and I need that to add itself to another FlowLayoutControl that's the Favourited song list, but I can't get that working, I can't have multiple base classes in the UserControl,and adding a public method to Form1, doesn't solve my issue, (it's not adding anything,tried it with listbox,but nothing).
I'm really stuck here,if someone can at least suggest something I would rly appreciate it.
Here is my SongItem
[Serializable]
public partial class SongItem : UserControl,Form
{
private String songName = "Song Name";
private String artistName = "Artist Name";
private Image thumbNail;
private String length;
private int maxLengthSongName = 25;
private int maxLengthArtistName = 25;
private Color colorHoverOn = Color.FromArgb(53,53,53);
private Color colorNormal = Color.FromArgb(53,53,53);
private SongData songData;
public SongItem()
{
InitializeComponent();
this.MouseClick += Control_MouseClick;
MouseEvents(this);
}
private void SongItem_Load(object sender, EventArgs e)
{
try
{
LoadData();
}
catch { }
LoadDataToUI();
}
#region GettersAndSetters
public int MaxLengthSongName
{
get { return maxLengthSongName; }
set { maxLengthSongName = value; }
}
public int MaxLengthArtistName
{
get { return maxLengthArtistName; }
set { maxLengthArtistName = value; }
}
public Color ColorHoverOn
{
get { return colorHoverOn; }
set { colorHoverOn = value; }
}
public Color ColorNormal
{
get { return colorNormal; }
set { colorNormal = value; }
}
public SongData SongData {
get{return songData; }
set { songData = value; }
}
#endregion
public void LoadData()
{
songName = songData.SongName;
artistName = songData.ArtistName;
thumbNail = songData.ThumbNail;
length = songData.Length;
}
void MouseEvents(Control container)
{
foreach (Control c in container.Controls)
{
c.MouseEnter += (s, e) => SongItem_MouseEnter(e);
c.MouseLeave += (s, e) => SongItem_MouseLeave(e);
c.MouseClick += Control_MouseClick;
MouseEvents(c);
};
}
private void SongNameLbl_MouseHover(object sender, EventArgs e)
{
if (songName.Length > maxLengthSongName) {
toolTip1.SetToolTip(songNameLbl, songName);
}
}
private void ArtistNameLbl_MouseHover(object sender, EventArgs e)
{
if (artistName.Length > maxLengthArtistName) {
toolTip1.SetToolTip(artistNameLbl, artistName);
}
}
private void SongNameLbl_Click(object sender, EventArgs e)
{
Clipboard.SetText(artistName + " " +songName);
}
#endregion
#region CurrentlySelected
public event EventHandler<EventArgs> WasClicked;
private void Control_MouseClick(object sender, MouseEventArgs e)
{
var wasClicked = WasClicked;
if (wasClicked != null)
{
WasClicked(this, EventArgs.Empty);
}
IsSelected = true;
}
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
this.BorderStyle = IsSelected ? BorderStyle.FixedSingle : BorderStyle.None;
}
}
#endregion
private void Fovourite_Click(object sender, EventArgs e)
{
Main newMain = new Main();
// newMain.AddSongToFavorite();
newMain.listBox1.Items.Add("Test");
}
}
}
Here is the the Form1 code
public void AddSongToFavorite() {
listBox1.Items.Add("Test");
//songList2.AddSong("Dire Straits - Sultans Of Swing");
MessageBox.Show("Hello", "Test");
// flowLayoutPanel1.Controls.Add(song);
}
Message shows up,but nothing else
I add the SongItem from another class
public partial class SongList : FlowLayoutPanel
{
public SongList()
{
InitializeComponent();
SongList_Load();
}
private void SongList_Load()
{
this.AutoScroll = true;
this.FlowDirection = FlowDirection.TopDown;
this.AutoSize = false;
this.WrapContents = false;
}
public async void AddSong(String songName) {
SongData song = await YoutubeSearch.GetSongInfo(songName);
// SongData song = XmlSerialization.ReadFromXmlFile<SongData>(Application.StartupPath + #"\test.txt");
SongItem songItem = new SongItem { SongData = song };
songItem.WasClicked += UsersGrid_WasClicked;
this.Controls.Add(songItem);
}
I fixed the problem by creating an EventHandler
In the main I created this public void
public void FavoriteWasClicked(object sender, EventArgs e) {
if (sender is SongItem)
{
songList2.AddSong(((SongItem)sender).SongData);
}
}
and on Form1 load I added (songList1 is the FlowLayoutPanel already added in the Form1 designer)
songList1.List_FavoriteWasClicked += FavoriteWasClicked;
I added this line to the FlowLayoutPanel class I created
public event EventHandler<EventArgs> List_FavoriteWasClicked;
and when creating new Controls(SongItems inside it)(Still part of FlowLayoutPanel)
public void AddSong(SongData song)
{
SongItem songItem = new SongItem { SongData = song };
songItem.FavoriteWasClicked += List_FavoriteWasClicked; ()
this.Controls.Add(songItem);
}
And now on the SongItem I created the custom event
public event EventHandler<EventArgs> FavoriteWasClicked;
and on the button I wanted to be the press to add to favorite list I added the following
FavoriteWasClicked(this, EventArgs.Empty);
Now when I press the button to add one Song to the liked/favorited list it's actually adding it.

Send Window as command parameter

I have got the following setup for my commands. I can't seem to figure out how I reference the window which my button is on, so that I can close it.
Is there some way I can use the command arguments ExecutedRoutedEventArgs e to reference the window and close it?
Button (on MainWindow.xaml)
<Button Command="Commands:MyCommands.CloseWindow">✖</Button>
Here are my commands, which are located in
Classes > Commands.cs
namespace Duplicate_Deleter.Classes
{
public class MyCommands
{
private static RoutedUICommand _CloseWindow;
private static RoutedUICommand _MinimizeWindow;
static MyCommands()
{
_CloseWindow = new RoutedUICommand("Close current window",
"CloseWindow", typeof(MyCommands));
_MinimizeWindow = new RoutedUICommand("Minimize current window",
"MinimizeWindow", typeof(MyCommands));
}
public static void BindCommandsToWindow(Window window)
{
window.CommandBindings.Add(
new CommandBinding(CloseWindow, CloseWindow_Executed, CloseWindow_CanExecute));
window.CommandBindings.Add(
new CommandBinding(MinimizeWindow, MinimizeWindow_Executed, MinimizeWindow_CanExecute));
}
// Command: CloseWindow
public static RoutedUICommand CloseWindow
{
get { return _CloseWindow; }
}
public static void CloseWindow_Executed(object sender,
ExecutedRoutedEventArgs e)
{
//Close window using e?
}
public static void CloseWindow_CanExecute(object sender,
CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
// Command: MinimizeWindow
public static RoutedUICommand MinimizeWindow
{
get { return _MinimizeWindow; }
}
public static void MinimizeWindow_Executed(object sender,
ExecutedRoutedEventArgs e)
{
MessageBox.Show("Minimize Window");
}
public static void MinimizeWindow_CanExecute(object sender,
CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
}
}
I bind the commands using a customized startup in
App.xaml.cs
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
//Startup
Window main = new MainWindow();
main.Show();
//Bind Commands
Classes.MyCommands.BindCommandsToWindow(main);
}
}
I tried this way and it works for me:
private void NewCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
var dObj = e.Source as DependencyObject;
if(dObj == null) return;
var parentWindow = dObj.GetVisualParentOfType<Window>();
if(parentWindow == null)
return;
parentWindow.Close();
}
Helper:
public static T GetVisualParentOfType<T>(this DependencyObject child)
where T : DependencyObject
{
var parentObject = VisualTreeHelper.GetParent(child);
if (parentObject == null) return null;
var parent = parentObject as T;
return parent ?? GetVisualParentOfType<T>(parentObject);
}
keep in mind that the helper method is an extension method that, put it in public static class.
regards

service is returning null wpf mvvm

I'm trying to bind data in my data context but service is returning null. I'm using ninject as DI. I'm sharing my app.xaml.cs code. Please guide me.
public partial class App
{
private IKernel container;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
AutoMapperConfig.RegisterMappings();
ConfigureContainer();
ComposeObjects();
Current.MainWindow.Show();
}
private void ConfigureContainer()
{
this.container = new StandardKernel();
container.Bind(typeof(IAppServiceBase<>)).To(typeof(AppServiceBase<>));
container.Bind<IJvDetailAppService>().To<JvDetailAppService>().InSingletonScope();
container.Bind<IJvMasterAppService>().To<JvMasterAppService>().InSingletonScope();
container.Bind<IJvDimensionAppService>().To<JvDimensionAppService>().InSingletonScope();
container.Bind(typeof(IServiceBase<>)).To(typeof(ServiceBase<>));
container.Bind<IJvDetailService>().To<JvDetailService>();
container.Bind<IJvMasterService>().To<JvMasterService>();
container.Bind<IJvDimensionService>().To<JvDimensionService>();
container.Bind(typeof(IRepositoryBase<>)).To(typeof(RepositoryBase<>));
container.Bind<IJvDetailRepository>().To<JvDetailRepository>();
container.Bind<IJvMasterRepository>().To<JvMasterRepository>();
container.Bind<IJvDimensionRepository>().To<JvDimensionRepository>();
}
private void ComposeObjects()
{
Current.MainWindow = this.container.Get<MainWindow>();
Current.MainWindow.Title = "JustApp";
}
}
MainWindowViewModel
public class MainWindowViewModel : ViewModelBase
{
private readonly BackgroundWorker _worker = new BackgroundWorker();
private ObservableCollection<JvDetailViewModelBase> _jvDetailMenu;
private readonly IJvDetailAppService _jvDetailAppService;
public ObservableCollection<JvDetailViewModelBase> JvDetailMenu
{
get { return this._jvDetailMenu; }
set
{
_jvDetailMenu = value;
RaisedPropertyChanged("JvDetailMenu");
}
}
public MainWindowViewModel()
{
_worker.DoWork += worker_DoWork;
_worker.RunWorkerCompleted += worker_RunWorkerCompleted;
_worker.RunWorkerAsync();
}
readonly ObservableCollection<JvDetailViewModelBase> _tempProductMenu = new ObservableCollection<JvDetailViewModelBase>();
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
_tempProductMenu.Add(new ModifyJvDetailViewModel(_jvDetailAppService));
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (_tempProductMenu.Any())
{
JvDetailMenu = _tempProductMenu;
}
}
}
ModifyJvDetailViewModel.cs
public class ModifyJvDetailViewModel : JvDetailViewModelBase
{
private readonly BackgroundWorker _worker = new BackgroundWorker();
private IEnumerable<JvDetail> _tempLoadJvDetails;
private readonly IJvDetailAppService _jvDetailAppService;
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
int ab = _jvDetailAppService.GetByCompanyId(3).Count(); // it is returning null here and everywhere which is fetching records.
_tempLoadJvDetails = _jvDetailAppService.GetByCompanyId(3);
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
JvDetails = _tempLoadJvDetails;
}
public override string Name
{
get { return JustAppHelper.JvDetail; }
}
public override string Icon
{
get { return JustAppHelper.JvDetailIcon; }
}
public ModifyJvDetailViewModel(IJvDetailAppService jvDetailAppService)
{
_jvDetailAppService = jvDetailAppService;
var ab = _jvDetailAppService.GetAll().Count();
_worker.DoWork += worker_DoWork;
_worker.RunWorkerCompleted += worker_RunWorkerCompleted;
_worker.RunWorkerAsync();
BindGrid();
}
protected void BindGrid()
{
JvDetails = _jvDetailAppService.GetByCompanyId(3);
}
private IEnumerable<JvDetail> _jvDetails;
public IEnumerable<JvDetail> JvDetails
{
get { return _jvDetails; }
set
{
_jvDetails = value;
RaisedPropertyChanged("JvDetails");
}
}
}
Mainwindow.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainWindowViewModel();
ListBoxProducts.SelectedIndex = 0;
}
}
One approach would be to change MainWindowViewModel constructor:
public MainWindowViewModel(IJvDetailAppService detailAppService)
{
_jvDetailAppService = detailAppService;
_worker.DoWork += worker_DoWork;
_worker.RunWorkerCompleted += worker_RunWorkerCompleted;
_worker.RunWorkerAsync();
}
and MainWindow constructor:
public MainWindow(IJvDetailAppService detailAppService)
{
InitializeComponent();
this.DataContext = new MainWindowViewModel(detailAppService);
ListBoxProducts.SelectedIndex = 0;
}

Categories