A usercontrol should get added every time when the shortcut is clicked. But when i close the usercontrol and try to open it again the shortcut doesn't work. The focus is somewhere else.when some button is clicked on the window and shortcut is clicked usercontrol is added.
UserControl 1:
<Window
x:class="Class1"
...>
<Window.InputBindings>
<KeyBinding Command="ButtonCLickCommand "
Modifiers="Control" Key="Q"/>
</Window.InputBindings>
<Grid x:Name="Grid">
<Button Content = "OpenUserControl" Command="ButtonCLickCommand "/>
<Button Content = "Temp"/>
</Grid>
</Window>
CodeBehind:
public ICommand ProfileCommand { get; set; }
ProfileCommand = new RelayCommand(Button_Click());
public void Button_Click()
{
_control = new Class2();
_control.CloseAction = CloseClass2;
Panel.SetZIndex(_control, 10);
_control.Width = 200;
_control.Height = 200;
Grid.Children.Add(_control);
}
public void CloseClass2(Class2 control)
{
Grid.Children.Remove(control);
}
UserControl 2:
<UserControl
x:class="Class2"
...>
<StackPanel>
<Button Content="x" Click="Button_Click" Height="30">
<Rectangle Fill="Black" Height="70"/>
</StackPanel>
</UserControl>
Code Behind:
namespace namespace1.UserControls
{
/// <summary>
/// Interaction logic for ProfileUserControl.xaml
/// </summary>
public partial class Class2 : UserControl
{
public Action<Class2> CloseAction;
public Class2()
{
InitializeComponent();
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
CloseAction(this);
}
}
}
This is outline of My code. Help me i'm new to WPF.
Thanks for every answer i get. :)
In Your KeyBinding ... you should bind to your command in View model
....
to make it easier .. it omit the view model ... here is the solution,note that i made some tweaks for simplicity:
in mainWindow.xaml :
<Window.InputBindings>
<KeyBinding Command="{Binding ButtonClickCommand,RelativeSource{RelativeSource FindAncestor,AncestorType=Window}}" Modifiers="Control" Key="Q"/>
</Window.InputBindings>
<StackPanel x:Name="MainGrid">
<Button Content = "OpenUserControl" Command="{Binding ButtonClickCommand,RelativeSource={RelativeSource FindAncestor,AncestorType=Window}}"/>
</StackPanel>
and here is the code behind:
public partial class MainWindow : Window
{
public RelayCommand ButtonClickCommand { get; set; }
public MainWindow()
{
InitializeComponent();
ButtonClickCommand= new RelayCommand(MyButtonClickExcute);
}
private void MyButtonClickExcute()
{
UserControl1 userControl1 = new UserControl1 {Width = 50, Height = 50,CloseAction = RemoveUserControlFromPanel };
Panel.SetZIndex(userControl1, 10);
MainGrid.Children.Add(userControl1);
}
public void RemoveUserControlFromPanel(UserControl1 userControl1)
{
MainGrid.Children.Remove(userControl1);
}
}
and for userControl.xaml:
<Grid>
<Border Background="Blue" CornerRadius="10" BorderThickness="15" BorderBrush="Green">
<Button VerticalAlignment="Center" HorizontalAlignment="Center" Width="125" Height="75" Content="Close" Click="ButtonBase_OnClick"></Button>
</Border>
</Grid>
finally, code behind for userControl:
public partial class UserControl1 : UserControl
{
public Action<UserControl1> CloseAction { get; set; }
public UserControl1()
{
InitializeComponent();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
CloseAction(this);
}
}
Related
Basically I have one textblock and 2 button, I want the textblock Text to change according to the button I click. For example, if I click on the Button 1, it will display, "Button 1 is click"
if I click on button 2, it will display "Button 2 is click"
This is my ViewModel
namespace ICommandProject2.ViewModel
{
class ViewModel
{
public ICommand myCommand { get; set; }
public ViewModel()
{
myCommand = new myCommand(ExecutedMethod);
}
private void ExecutedMethod (object parameter)
{
MainWindow m = new MainWindow();
m.txtBlock.Text = "Button 1 is click";
}
}
}
This my Command Class
namespace ICommandProject2.Command
{
class myCommand : ICommand
{
Action<object> actionExecuted;
public myCommand(Action<object> ExecutedMethod)
{
actionExecuted = ExecutedMethod;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
actionExecuted(parameter);
}
}
}
This is my Mainwindow.xaml
<Window x:Class="ICommandProject2.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:ICommandProject2.ViewModel"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:ViewModel x:Key="vm"/>
</Window.Resources>
<Grid>
<Button x:Name="btnOne" Content="Button 1" Command="{Binding myCommand, Source={StaticResource vm}}" HorizontalAlignment="Left" Margin="273,232,0,0" VerticalAlignment="Top" Width="75" FontSize="18"/>
<TextBlock x:Name="txtBlock" HorizontalAlignment="Left" Margin="273,89,0,0" TextWrapping="Wrap" Text="This is a textblock" VerticalAlignment="Top" FontSize="36"/>
<Button x:Name="btnTwo" Content="Button 2" HorizontalAlignment="Left" Margin="495,232,0,0" VerticalAlignment="Top" Width="75" FontSize="18" />
</Grid>
</Window>
When I click on the button, nothing is happening, what should I change?
use binding to set TextBlock text.
create a property fro binding in a view model and change that property in command handler:
class ViewModel : INotifyPropertyChanged
{
public ICommand myCommand { get; set; }
private string _title = "This is a textblock";
public string Title { get { return _title; } }
public ViewModel()
{
myCommand = new myCommand(ExecutedMethod);
}
private void ExecutedMethod (object parameter)
{
_title = "Button 1 was clicked";
OnPropertyChanged("Title");
}
}
I omitted that part, but you should implement INotifyPropertyChanged to notify view about changes in a view model.
use Binding in a view:
<TextBlock x:Name="txtBlock" Text="{Binding Title}" ...
(command as it is now doesn't work becuase it creates an new instance of Window (MainWindow m = new MainWindow();) instead of working with open Window)
I have a ListBox I want to fill with data from two TextBoxesby clicking a Button. I think the problem comes from the differents textblock i have in my listbox. Here is what i want in image :
TheUI
The MainWindow.xaml of my listbox :
<ListBox x:Name="listBox"
ItemsSource="{Binding Issues}" Grid.Column="1" HorizontalAlignment="Left" Height="366" VerticalAlignment="Top" Width="453" Margin="0,0,-1,0">
<StackPanel Margin="3">
<DockPanel >
<TextBlock FontWeight="Bold" Text="Issue:"
DockPanel.Dock="Left"
Margin="5,0,10,0"/>
<TextBlock Text=" " />
<TextBlock Text="{Binding Issue}" Foreground="Green" FontWeight="Bold" />
</DockPanel>
<DockPanel >
<TextBlock FontWeight="Bold" Text="Comment:" Foreground ="DarkOrange"
DockPanel.Dock="Left"
Margin="5,0,5,0"/>
<TextBlock Text="{Binding Comment}" />
</DockPanel>
</StackPanel>
</ListBox>
My MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public sealed class ViewModel
{
public ObservableCollection<Issue> Issues { get; private set; }
public ViewModel()
{
Issues = new ObservableCollection<Issue>();
}
}
private void addIssue_Click(object sender, RoutedEventArgs e)
{
var vm = new ViewModel();
vm.Issues.Add(new Issue { Name = "Jon Skeet", Comment = "lolilol" });
DataContext = vm;
InitializeComponent();
}
}
My Issue.cs :
public sealed class Issue
{
public string Name { get; set; }
public string Comment { get; set; }
}
I follow this tutorial but i don't want to implement a Database :
Tuto
I also try to use this stackoverflow question
The error i have is 'System.InvalidOperationException' The Items collection must be empty to use ItemsSource
But not sure this is the heart of the problem.
Remove whatever you have inserted between <ListBox> and </ListBox>, as it is treated as part of Items collection.
Instead shift that content between <ListBox.ItemTemplate>...</ListBox.ItemTemplate>.
You don't need to update Context and InitializeComponent every time, atleast to your case.
public partial class MainWindow : Window
{
ViewModel vm = new ViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = vm;
}
public sealed class ViewModel
{
public ObservableCollection<Issue> Issues { get; private set; }
public ViewModel()
{
Issues = new ObservableCollection<Issue>();
}
}
private void addIssue_Click(object sender, RoutedEventArgs e)
{
vm.Issues.Add(new Issue { Name = "Jon Skeet", Comment = "lolilol" });
}
}
I've a simple TreeView in my WPF application. The content is build up programmatically adding several TreeViewItems (and sub items).
Now I want to integrate links in each TreeViewItem like
"Text of Item 1 (http://google.de)"
The links should be clickable.
How can I achieve this in the code and how can I assign a handler to perform the "Hyperlink Action" ( e.g. Process.Start(linkStr) )?
XAML file:
<Window x:Class="SOTree.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TreeView Grid.Row="0" Grid.Column="1" Margin="30">
My Treeview Title
<TreeViewItem IsExpanded="True">
<TextBlock IsEnabled="True">Wikipedia
<Hyperlink NavigateUri="http://www.wikipedia.org" RequestNavigate="Hyperlink_RequestNavigate">
Wikipedia
</Hyperlink>
</TextBlock>
</TreeViewItem>
</TreeView>
</Grid>
Code behind:
using System.Windows;
using System.Windows.Navigation;
namespace SOTree
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
System.Diagnostics.Process.Start(e.Uri.ToString());
}
}
}
Hope this helps.
XAML for Tree view
<TreeView Name="trvMenu" Margin="367,29,0.2,154.6">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type l:MenuItem}" ItemsSource="{Binding Items}">
<TextBlock>
<Hyperlink NavigateUri="{Binding Title}"
RequestNavigate="Hyperlink_RequestNavigate">
<InlineUIContainer>
<TextBlock Text="{Binding Title}" />
</InlineUIContainer>
</Hyperlink></TextBlock>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Code Behind with binding
public class MenuItem
{
public MenuItem()
{
this.Items = new ObservableCollection<MenuItem>();
}
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
public string Title { get; set; }
public ObservableCollection<MenuItem> Items { get; set; }
}
public partial class MainWindow : Window
{
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
e.Handled = true;
}
public MainWindow()
{
InitializeComponent();
MenuItem root = new MenuItem() { Title = "Menu" };
MenuItem childItem1 = new MenuItem() { Title = "http://www.google.com" };
childItem1.Items.Add(new MenuItem() { Title = "http://www.google.com" });
childItem1.Items.Add(new MenuItem() { Title = "http://www.google.com" });
root.Items.Add(childItem1);
root.Items.Add(new MenuItem() { Title = "http://www.google.com" });
trvMenu.Items.Add(root);
}
}
Having a main c# class CtrlMain with method testForm it opens a WPF form (testFormCtrl)that shows a textbox and assigns a variable Xmin with the value introduced on textbox.
I want to execute method wantToExe from opened wpf user control with value introduced on textbox as a parameter
Here is what I have:
public partial class CtrlMain : UserControl
{
int mCounter;
double firstPos;
double[] currentBounds;
//ETC..
//constructor and class methods
//this opens a user control
static void testForm()
{
GenericWindow goWin;
testFormCtrl mytestFormCtrl = new testFormCtrl();
goWin = new GenericWindow(App.Current.MainWindow, mytestFormCtrl);
goWin.Title = "test";
goWin.ShowDialog();
}
//how to call this method with parameter of textbox?
public double wantToExe(double externalX){
double result;
//DO SOME COMPUTING
return result;
}
}
the testFormCtrl xaml is:
<UserControl x:Class="testFormCtrl"
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:telerik="http://schemas.telerik.com/2008/xaml/presentation"
mc:Ignorable="d">
<Grid Height="300">
<Grid>
<GroupBox Header="Location" Height="93" HorizontalAlignment="Left" Margin="4,3,0,0" Name="GBoxGridDefinition" VerticalAlignment="Top" Width="624">
<Grid>
<TextBlock Height="20" HorizontalAlignment="Left" Margin="20,13,0,0" Name="TblockXmin" Text="Xmin:" VerticalAlignment="Top" Width="36" />
<TextBox Name="TextBoxXmin" Height="20" Width="89" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="59,9,0,0" Text="{Binding Path=Xmin, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True,NotifyOnValidationError=True}" >
</TextBox>
<telerik:RadButton Content="Execute X" IsEnabled="True" Height="22" HorizontalAlignment="Left" Margin="484,9,0,0" Name="ButtonExecuteX" VerticalAlignment="Top" Width="102" telerik:StyleManager.Theme="Vista" />
</Grid>
</GroupBox>
</Grid>
</Grid>
</UserControl>
and c# code is
public partial class testFormCtrl : UserControl
{
double gnXmin;
public event PropertyChangedEventHandler PropertyChanged;
public double Xmin
{
get { return gnXmin; }
set
{
gnXmin = value;
OnPropertyChanged("Xmin");
}
}
void OnPropertyChanged(string lcProperty)
{
if (this.PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(lcProperty));
}
}
public testFormCtrl ()
{
InitializeComponent();
}
private void ButtonExecuteX_Click(object sender, RoutedEventArgs e)
{
//how to call CtrlMain.wantToExe(Xmin) ???
}
}
}
How can I call that method from other class, I can not make it static....
Just create a new constructor for your testFormCtrl class that accepts CtrlMain as a parameter:
private CtrlMain _caller;
public testFormCtrl(CtrlMain caller)
: this()
{
_caller = caller;
}
Then you can just invoke its methods:
private void ButtonExecuteX_Click(object sender, RoutedEventArgs e)
{
if(_caller != null) caller.wantToExe(Xmin);
}
Remember to pass the instance of CtrlMain in your testForm method:
static void testForm()
{
GenericWindow goWin;
testFormCtrl mytestFormCtrl = new testFormCtrl(this); //use the new constructor
goWin = new GenericWindow(App.Current.MainWindow, mytestFormCtrl);
goWin.Title = "test";
goWin.ShowDialog();
}
I have created a program that changes the name in a TextBox when check or unckeck a Checkbox. I want to replicate this Textbox in a different window. I thought with Data Mining in the xaml would be possible, but the name only appears in one window. Second window window does´t recieve the data. I show you the code of the two windows.
Can you help me? Thankss
Window 1.cs---
namespace WpfApplication1
{
public partial class Window1 : Window
{
Texto prueba = new Texto("Carlos");
public static string s;
public Window1()
{
InitializeComponent( );
// Fill initial person fields
this.textBox1.Text = prueba.Name;
}
private void checkBox1_Checked(object sender, RoutedEventArgs e)
{
prueba.Name="Carlos";
textBox1.DataContext = prueba;
textBox1.Text = prueba.Name;
}
private void checkBox1_UnChecked(object sender, RoutedEventArgs e)
{
prueba.Name = "Luis";
textBox1.DataContext = prueba;
textBox1.Text = prueba.Name;
}
}
public class Texto
{
string name;
public string Name
{
get { return this.name; }
set { this.name = value; }
}
public Texto( ) {}
public Texto(string name)
{
this.name = name;
}
}
}
window1 xaml-------
<Grid>
<CheckBox Content="CheckBox" Height="16" HorizontalAlignment="Left" Margin="62,118,0,0" Name="checkBox1" VerticalAlignment="Top" Checked="checkBox1_Checked" Unchecked="checkBox1_UnChecked" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="44,140,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
</Grid>
window2 cs-----
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
Window1 nueva = new Window1();
nueva.Show();
}
}
}
window2 xaml--------
<Grid>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="82,121,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<TextBox DataContext="prueba" Text="{Binding Path=Name}" Height="23" HorizontalAlignment="Left" Margin="57,84,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" />
</Grid>
You will have to pass a reference to either the first window or the object that you're updating the text property on to the second window, it's DataContext property will do for that, you can then bind the second windows controls to it.
In this demo application I've created a MainWindow and a second window (Window1), the application starts in Main window like this.
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public string TestString
{
get { return (string)GetValue(TestStringProperty); }
set { SetValue(TestStringProperty, value); }
}
public static readonly DependencyProperty TestStringProperty = DependencyProperty.Register("TestString", typeof(string), typeof(MainWindow), new UIPropertyMetadata(null));
public MainWindow()
{
InitializeComponent();
// setup the test string.
TestString = "this is a test.";
// Create the second window and pass this window as it's data context.
Window1 newWindow = new Window1()
{
DataContext = this
};
newWindow.Show();
}
}
MainWindow.xaml - Take note of the DataContext line in the Window declaration.
<Window x:Class="WpfApplication5.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
>
<Grid>
<TextBox Text="{Binding TestString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="91,84,185,189" />
</Grid>
</Window>
Now for Window1 the code behind is just an empty default window class so I won't post it but the xaml is.
Window1.xaml
<Window x:Class="WpfApplication5.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<TextBlock Text="{Binding TestString, UpdateSourceTrigger=PropertyChanged}"/>
</Grid>
</Window>
Don't set the DataContext explicitly, or only via another Binding. Your
<TextBox DataContext="prueba"
does nothing helpful. DataContext will be inherited as long as it is not overwritten. Don't set it explicitly. It should be enought to set it once on both windows.
Create your data object in your MainWindow
Texto prueba = new Texto("Carlos");
Window1 nueva = new Window1();
nueva.DataContext = prueba;
nueva.Show();
and remove all the other DataContext assignments.
A couple of things wrong here, but I can probably give you a quick solution to fix your problem. First off your DataContext on window 2 isn't working properly, you can set it exclusively in your code right before you show window1...
private void button1_Click(object sender, RoutedEventArgs e)
{
Window1 nueva = new Window1();
this.DataContext = nueva.prueba;
nueva.Show();
}
Next you have to fire INotifyPropertyChanged in your Texto class...
public class Texto : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string name;
public string Name
{
get { return this.name; }
set
{
this.name = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Name"));
}
}
public Texto( ) {}
public Texto(string name)
{
this.name = name;
}
}
If both textboxes share a common datacontext it will "just work" without any code required...