WPF: Adding ContexMenu to Dynamically Created Tree - c#

Hi all I am trying to add ContexMenu into my Dynamically generated Tree.
Below is my Code For generating Tree.
I need to add ContexMenu for :
NEW:
EDIT:
DELETE
on MouseClick I should be able to perform the same operation of clicking the Respective Buttons.
Can any body help in completing the code.
XML:CODE
<Window x:Class="NewTree_DynamicNode.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"
Loaded="TestsTreeViewPageFunction_Loaded">
<Grid>
<TreeView Name="treeFileSystem" >
<TreeViewItem Header="Suite" Name="MYTree" Tag="hi" IsExpanded="True">
<TreeViewItem Name="treeFileSystem1" />
</TreeViewItem>
</TreeView>
<TextBox Name="textBox1" Height="23" HorizontalAlignment="Left" Margin="121,150,0,0" VerticalAlignment="Top" Width="120" />
<Button Content="New" Height="23" HorizontalAlignment="Left" Margin="12,121,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="New_Click" />
<Button Content="Edit" Height="23" HorizontalAlignment="Left" Margin="12,150,0,0" Name="button2" VerticalAlignment="Top" Width="75" Click="Edit_Click"/>
<Button Content="Copy" Height="23" HorizontalAlignment="Left" Margin="12,179,0,0" Name="button3" VerticalAlignment="Top" Width="75" Click="Copy_Click"/>
</Grid>
</Window>
C# CODE:
private void TestsTreeViewPageFunction_Loaded(object sender,
RoutedEventArgs e)
{
this.MYTree.Items.Clear();
for (int j = 1; j < 4; j++)
{
TreeViewItem Case = new TreeViewItem();
Case.Header = "Case "+j.ToString();
Case.IsExpanded = true;
Case.Items.Add(Trythis());
this.MYTree.Items.Add(Case);
}
}
private TreeViewItem Trythis()
{
TreeViewItem Step = new TreeViewItem();
for (int i = 0; i < 5; i++)
{
Step.Header = "Steps " + i.ToString();
}
return Step;
}
private void New_Click(object sender, RoutedEventArgs e)
{
textBox1.Text = "New Button Clicked";
}
private void Edit_Click(object sender, RoutedEventArgs e)
{
textBox1.Text = "Edit Button Clicked";
}
private void Copy_Click(object sender, RoutedEventArgs e)
{
textBox1.Text = "Copy Button Clicked";
}
EDIT:
I am looking for a solution where I should be able to add or limit the ContexMenu to TreeItem based on there Header information.

You can use style to set common ContextMenu property:
<TreeViewItem Header="Suite" Name="MYTree" Tag="hi" IsExpanded="True">
<TreeViewItem.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu>
<MenuItem Header="New" />
<MenuItem Header="Edit" />
<MenuItem Header="Delete" />
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</TreeViewItem.Resources>
<TreeViewItem x:Name="treeFileSystem1" />
</TreeViewItem>
Or you can add context menu in code: before line this.MYTree.Items.Add(Case);
you can add something like this:
var menu = new ContextMenu();
menu.Children.Add(new MenuItem{Header = "Save"});
menu.Children.Add(new MenuItem{Header = "Load"});
Case.ContextMenu = menu;

Related

WPF TextBox Command Binding

I am using two TextBox and "Save" Button. Basically, the "Save" button will be enabled when TextBox has any Text changed. I created a CommandBinding in the Window.Resource and "Save" Button uses Command="Save" and Two TextBox use StaticResources for Command binding.
However, the Button is not enabled when I change the text. Use Debug, I can see that my flag for the TextBox text changed is True but it looks like TextBox didn't trigger the Save Command CanExecuted Event.
Below is my code.
xaml
<Window>
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.New" Executed="NewCommand_Executed" />
<CommandBinding Command="{x:Static commands:DataCommands.Requery}" Executed="RequeryCommand_Executed"/>
<CommandBinding Command="{x:Static commands:DataCommands.ApplicationUndo}"
Executed="ApplicationUndo_OnExecuted" CanExecute="ApplicationUndo_OnCanExecute"/>
</Window.CommandBindings>
<Window.Resources>
<CommandBinding x:Key="Binding" Command="ApplicationCommands.Save"
Executed="SaveCommand_Executed" CanExecute="SaveCommand_CanExecute"/>
</Window.Resources>
<StackPanel>
<Menu>
<MenuItem Header="File">
<MenuItem Command="New"/>
</MenuItem>
</Menu>
<StackPanel Orientation="Horizontal" Margin="5">
<Button Name="New" Command="New" Content="New" Margin="3" Padding="3"/>
<Button Name="Save" Command="Save" Content="Save" Margin="3" Padding="3"/>
...
</StackPanel>
<TextBox Name="TbInputText1" TextChanged="TbInputText_OnTextChanged" Margin="5">
<TextBox.CommandBindings>
<StaticResource ResourceKey="Binding"/>
</TextBox.CommandBindings>
</TextBox>
<TextBox Name="TbInputText2" Margin="5" TextChanged="TbInputText_OnTextChanged">
<TextBox.CommandBindings>
<StaticResource ResourceKey="Binding"/>
</TextBox.CommandBindings>
</TextBox>
<ListBox Name="LsbHistory" DisplayMemberPath="Name" Margin="3"></ListBox>
</StackPanel>
behind-code
public partial class UseCommand : Window
{
private Dictionary<Object, bool> _isDirty = new Dictionary<Object, bool>();
public UseCommand()
{
InitializeComponent();
this.AddHandler(CommandManager.PreviewExecutedEvent,
new ExecutedRoutedEventHandler(CommandExecuted));
}
private void TbInputText_OnTextChanged(object sender, TextChangedEventArgs e)
{
// _isDirty.Add(sender, true);
_isDirty[sender] = true;
}
#region Save
private void SaveCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (_isDirty.ContainsKey(sender) && _isDirty[sender])
{
e.CanExecute = true;
}
else
{
// MessageBox.Show(sender.ToString());
e.CanExecute = false;
}
}
private void SaveCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
string text = ((TextBox)sender).Text;
MessageBox.Show("About this controller: " + sender.ToString() +
"Contents: " + text);
_isDirty[sender] = false;
}
#endregion
}
Is there any step I missed? Why CanExecuted didn't be triggerd?
You have to move your save CommandBinding to <Window.CommandBindings> collection from the <Window.Resource> collection
remove the x:Key attribute
Set the Command property of your button to ""ApplicationCommands.Save"
<Window.CommandBindings>
<CommandBinding
CanExecute="SaveCommand_CanExecute"
Command="ApplicationCommands.Save"
Executed="SaveCommand_Executed"/>
(...)
</Window.CommandBindings>
<StackPanel>
(...)
<Button
Name="Save"
Margin="3"
Padding="3"
Command="ApplicationCommands.Save"
Content="Save"
/>
(...)

C# XAML and Code isses

I'm trying to finish off this program but I have a few errors that I can't get rid of. I've been following the C# book I have as well, and I can't seem to find missing steps. I'll post the XAML code and the regular code.
Errors I have are as followed...
Warning 3 Unreachable code detected
Error 1 The type or namespace name 'memberSince' could not be found (are you missing a using directive or an assembly reference?)
Error 4 The type or namespace name 'Member' could not be found (are you missing a using directive or an assembly reference?)
Error 5 The type or namespace name 'Member' could not be found (are you missing a using directive or an assembly reference?)
Error 6 Delegate 'System.Threading.ParameterizedThreadStart' does not take 0 arguments
Error 2 'BellRingers.MainWindow.memberSince' is a 'field' but is used like a 'type'
XAML:
<Window x:Class="BellRingers.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Middleshire Bell Ringers Association - Members" Height="470" Width="600" Closing="Window_Closing">
<Window.Resources>
<Style x:Key="bellRingersFontStyle" TargetType="Control">
<Setter Property="FontFamily" Value="Comic Sans MS" />
</Style>
<Style x:Key="bellRingersStyle" TargetType="Control">
<Setter Property="Background" Value="Gray" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontFamily" Value="Comic Sans MS" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Blue" />
</Trigger>
</Style.Triggers>
</Style>
<ContextMenu x:Key="textBoxMenu" Style="{StaticResource bellRingersFontStyle}" >
<MenuItem Header="Clear Name" Name="clearName" Click="clearName_Click" />
</ContextMenu>
</Window.Resources>
<Grid>
<Image Panel.ZIndex="0" Margin="0,0,0,0" Name="image1" >
<Image.Source>
<BitmapImage UriSource="bell.gif" />
</Image.Source>
</Image>
<Label Content="First Name" Height="28" HorizontalAlignment="Left" Margin="29,25,0,0" Name="label1" VerticalAlignment="Top" Width="75" Style="{StaticResource bellRingersFontStyle}" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="121,25,0,0" Name="firstName" ContextMenu="{StaticResource textBoxMenu}" VerticalAlignment="Top" Width="175" Style="{StaticResource bellRingersStyle}" IsEnabled="False" />
<Label Content="Last Name" Height="28" HorizontalAlignment="Left" Margin="302,25,0,0" Name="label2" VerticalAlignment="Top" Width="75" Style="{StaticResource bellRingersFontStyle}" />
<TextBox Height="23" HorizontalAlignment="Left" Margin="380,25,0,0" Name="lastName" ContextMenu="{StaticResource textBoxMenu}" VerticalAlignment="Top" Width="175" Style="{StaticResource bellRingersStyle}" IsEnabled="False" />
<Label Content="Tower" Height="28" HorizontalAlignment="Left" Margin="29,72,0,0" Name="label3" VerticalAlignment="Top" Width="75" Style="{StaticResource bellRingersFontStyle}" />
<ComboBox Height="23" HorizontalAlignment="Left" Margin="121,72,0,0" Name="towerNames" VerticalAlignment="Top" Width="275" Style="{StaticResource bellRingersFontStyle}" IsEnabled="False" />
<CheckBox Content="Captain" Height="23" HorizontalAlignment="Left" Margin="420,72,0,0" Name="isCaptain" VerticalAlignment="Top" Width="75" Style="{StaticResource bellRingersFontStyle}" IsEnabled="False" />
<Label Content="Member Since" Height="28" HorizontalAlignment="Left" Margin="29,134,0,0" Name="label4" VerticalAlignment="Top" Width="90" Style="{StaticResource bellRingersFontStyle}" />
<DatePicker Height="23" HorizontalAlignment="Left" Margin="121,134,0,0" Name="memberSince" VerticalAlignment="Top" Width="275" IsEnabled="False" />
<GroupBox Header="Experience" Height="200" HorizontalAlignment="Left" Margin="29,174,0,0" Name="yearsExperience" VerticalAlignment="Top" Width="258" Style="{StaticResource bellRingersFontStyle}" IsEnabled="False">
<StackPanel Margin="0,0,0,0" Name="stackPanel1">
<RadioButton Content="Up to 1 year" Height="16" Name="novice" Width="120" Margin="0, 10, 0, 0" />
<RadioButton Content="1 to 4 years" Height="16" Name="intermediate" Width="120" Margin="0, 20, 0, 0" />
<RadioButton Content="5 to 9 years" Height="16" Name="experienced" Width="120" Margin="0, 20, 0, 0" />
<RadioButton Content="10 or more" Height="16" Name="accomplished" Width="120" Margin="0, 20, 0, 0" />
</StackPanel>
</GroupBox>
<ListBox Height="200" HorizontalAlignment="Left" Margin="310,174,0,0" Name="methods" VerticalAlignment="Top" Width="245" Style="{StaticResource bellRingersFontStyle}" IsEnabled="False" />
<Button Content="Clear" Height="23" HorizontalAlignment="Left" Margin="313,378,0,0" Name="clear" VerticalAlignment="Top" Width="75" Style="{StaticResource bellRingersStyle}" Click="clear_Click" IsEnabled="False" />
<DockPanel Height="100" HorizontalAlignment="Stretch" Margin="0" Name="dockPanel1" VerticalAlignment="Top" Width="Auto">
<Menu Style="{StaticResource bellRingersFontStyle}" Height="23" Name="menu1" Width="Auto" DockPanel.Dock="Top" VerticalAlignment="Top">
<MenuItem Header="_File">
<MenuItem Header="_New Member" Name="newMember" Click="newMember_Click" >
<MenuItem.Icon>
<Image Source="Face.bmp" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="_Save Member Details" Name="saveMember" IsEnabled="False" Click="saveMember_Click">
<MenuItem.Icon>
<Image Source="Note.bmp" />
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="E_xit" Name="exit" Click="exit_Click" />
</MenuItem>
<MenuItem Header="_Help">
<MenuItem Header="_About Middleshire Bell Ringers" Name="about" Click="about_Click" >
<MenuItem.Icon>
<Image Source="Ring.bmp" />
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
</DockPanel>
<StatusBar Height="23" HorizontalAlignment="Stretch" Margin="0" Name="status" VerticalAlignment="Bottom" Width="Auto" Style="{StaticResource bellRingersFontStyle}" />
</Grid>
Code-behind:
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private string[] towers = { "Great Shevington", "Little Mudford",
"Upper Gumtree", "Downley Hatch" };
private string[] ringingMethods = {"Plain Bob", "Reverse Canterbury",
"Grandsire", "Stedman", "Kent Treble Bob", "Old Oxford Delight",
"Winchendon Place", "Norwich Suprise", "Crayford Little Court" };
private ContextMenu windowContextMenu = null;
public MainWindow()
{
InitializeComponent();
this.Reset();
MenuItem saveMemberMenuItem = new MenuItem();
saveMemberMenuItem.Header = "Save Member Details";
saveMemberMenuItem.Click += new RoutedEventHandler(saveMember_Click);
MenuItem clearFormMenuItem = new MenuItem();
clearFormMenuItem.Header = "Clear Form";
clearFormMenuItem.Click += new RoutedEventHandler(clear_Click);
windowContextMenu = new ContextMenu();
windowContextMenu.Items.Add(saveMemberMenuItem);
windowContextMenu.Items.Add(clearFormMenuItem);
}
public void Reset()
{
firstName.Text = String.Empty;
lastName.Text = String.Empty;
towerNames.Items.Clear();
foreach (string towerName in towers)
{
towerNames.Items.Add(towerName);
}
towerNames.Text = towerNames.Items[0] as string;
methods.Items.Clear();
CheckBox method = null;
foreach (string methodName in ringingMethods)
{
method = new CheckBox();
method.Margin = new Thickness(0, 0, 0, 10);
method.Content = methodName;
methods.Items.Add(method);
}
isCaptain.IsChecked = false;
novice.IsChecked = true;
memberSince.Text = DateTime.Today.ToString();
}
private void clear_Click(object sender, RoutedEventArgs e)
{
this.Reset();
}
//private void add_Click(object sender, RoutedEventArgs e)
//{
// string nameAndTower = String.Format(
// "member name: {0} {1} from the tower at {2} rings the following methods:",
// firstName.Text, lastName.Text, towerNames.Text);
// StringBuilder details = new StringBuilder();
// details.AppendLine(nameAndTower);
// foreach (CheckBox cb in methods.Items)
// {
// if (cb.IsChecked.Value)
// {
// details.AppendLine(cb.Content.ToString());
// }
// }
// MessageBox.Show(details.ToString(), "Member Information");
//}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
MessageBoxResult key = MessageBox.Show(
"Are you sure you want to quit",
"Confirm",
MessageBoxButton.YesNo,
MessageBoxImage.Question,
MessageBoxResult.No);
e.Cancel = (key == MessageBoxResult.No);
}
private void newMember_Click(object sender, RoutedEventArgs e)
{
this.Reset();
saveMember.IsEnabled = true;
firstName.IsEnabled = true;
lastName.IsEnabled = true;
towerNames.IsEnabled = true;
isCaptain.IsEnabled = true;
memberSince.IsEnabled = true;
yearsExperience.IsEnabled = true;
methods.IsEnabled = true;
clear.IsEnabled = true;
this.ContextMenu = windowContextMenu;
}
private void exit_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
private void saveData(string fileName, memberSince member)
{
using (StreamWriter writer = new StreamWriter(fileName))
{
writer.WriteLine("First Name: {0}", member.FirstName);
writer.WriteLine("Last Name: {0}", member.LastName);
writer.WriteLine("Tower: {0}", member.TowerName);
writer.WriteLine("Captain: {0}", member.IsCaptain.ToString());
writer.WriteLine("Member Since: {0}", member.MemberSince.ToString());
writer.WriteLine("Methods: ");
foreach (string method in member.Methods)
{
writer.WriteLine(method);
}
Thread.Sleep(10000);
Action action = new Action(() =>
{
status.Items.Add("Member details saved");
});
this.Dispatcher.Invoke(action, DispatcherPriority.ApplicationIdle);
}
}
private void saveMember_Click(object sender, RoutedEventArgs e)
{
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.DefaultExt = "txt";
saveDialog.AddExtension = true;
saveDialog.FileName = "Members";
saveDialog.InitialDirectory = #"C:\Users\John\Documents";
saveDialog.OverwritePrompt = true;
saveDialog.Title = "Bell Ringers";
saveDialog.ValidateNames = true;
if (saveDialog.ShowDialog().Value)
{
Member member = new Member();
member.FirstName = firstName.Text;
member.LastName = lastName.Text;
member.TowerName = towerNames.Text;
member.IsCaptain = isCaptain.IsChecked.Value;
member.MemberSince = memberSince.SelectedDate.Value;
member.Methods = new List<string>();
foreach (CheckBox cb in methods.Items)
{
if (cb.IsChecked.Value)
{
member.Methods.Add(cb.Content.ToString());
}
}
Thread workerThread = new Thread(
() => this.saveData(saveDialog.FileName, member));
workerThread.Start();
}
}
private void about_Click(object sender, RoutedEventArgs e)
{
About aboutWindow = new About();
aboutWindow.ShowDialog();
}
private void clearName_Click(object sender, RoutedEventArgs e)
{
firstName.Clear();
lastName.Clear();
}
}
}
Just add one more attributes to your DatePicker field in xaml
<DatePicker x:Name="memberSince" Height="23" HorizontalAlignment="Left" Margin="121,134,0,0" Name="memberSince" VerticalAlignment="Top" Width="275" IsEnabled="False" />
Then in you code behind you can directly access memberSince directly. That is your Error 2. You need to do this changes to all fields necessary
I guess your mistake is here:
private void saveData(string fileName, memberSince member)
{
...
}
in the saveData method definition you specify "memberSince" as a parameter type,but it is your DatePicker name,not a type.
and second mistake i can't see your Member class definition too,check these issues and come again.
edit- solution:
Change your saveData method definition like this replace memberSince with Member:
private void saveData(string fileName, Member member)
{
...
}
And make sure you define your Member class.
You need to have a Structure called Member, something like this:
struct Member
{
public string FirstName;
public string LastName;
public string TowerName;
public bool IsCaptain;
public DateTime MemberSince;
public List<string> Methods;
}
then change your the saveData Method's signature to this.
private void saveData(string fileName, Member member)
{ ...
Doing this cleared all of the errors for me.

Hide/Display XAML elements or block LostFocus event

I have a page containing two StackPanels, each containing one TextBox and one Button:
<StackPanel x:Name="Row1">
<TextBox x:Name="TextBox1" Text="" GotFocus="OnFocusHandler" LostFocus="OffFocusHandler"/>
<Button x:Name="Button1" Content="Convert" Click="OnClickHandler" Visibility="Collapsed"/>
</StackPanel>
<StackPanel x:Name="Row2">
<TextBox x:Name="TextBox2" Text="" GotFocus="OnFocusHandler" LostFocus="OffFocusHandler"/>
<Button x:Name="Button2" Content="Convert" Click="OnClickHandler" Visibility="Collapsed"/>
</StackPanel>
I would like to do the following:
When a textbox has focus, the other textbox must be hidden and the corresponding button must show
When a textbox is out of focus, we are back to the original display: only empty textboxes are visible
I don't want the button to be able to trigger the OffFocusHandler
This is the current code that I have for the three handlers:
private void OnFocusHandler(object sender, RoutedEventArgs e)
{
TextBox SenderTextBox = (TextBox)sender;
if (SenderPanel.Name == "TextBox1")
{
Button1.Visibility = Visibility.Visible;
}
else if (SenderPanel.Name == "TextBox2")
{
Button2.Visibility = Visibility.Visible;
}
}
private void OffFocusHandler(object sender, RoutedEventArgs e)
{
TextBox1.Text = "";
TextBox2.Text = "";
Button1.Visibility = Visibility.Collapsed;
Button2.Visibility = Visibility.Collapsed;
}
private void OnClickHandler(object sender, RoutedEventArgs e)
{
// some stuff unrelated to my issue
}
How do I avoid the button clicking to trigger the OffFocusHandler code?
Is there another way to code this? I'm a complete beginner so I may not think the right way.
You can just Bind to the TextBox.IsFocused property in Xaml, and use the BooleanToVisibilityConverter to show/hide the button.
Example:
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
Title="MainWindow" Height="300" Width="400" Name="UI" >
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolTovisible" />
</Window.Resources>
<Grid>
<StackPanel x:Name="Row1" Height="54" VerticalAlignment="Top">
<TextBox x:Name="TextBox1" Text="" />
<Button x:Name="Button1" Content="Convert" Visibility="{Binding ElementName=TextBox1, Path=IsFocused, Converter={StaticResource BoolTovisible}}"/>
</StackPanel>
<StackPanel x:Name="Row2" Margin="0,60,0,0" Height="51" VerticalAlignment="Top">
<TextBox x:Name="TextBox2" Text="" />
<Button x:Name="Button2" Content="Convert" Visibility="{Binding ElementName=TextBox2, Path=IsFocused, Converter={StaticResource BoolTovisible}}"/>
</StackPanel>
</Grid>
</Window>
for each element, there is a Visibility tag, it is "Visible" by default but you can assign "Hidden" or "Collapsed" as follow:
<RadioButton Margin="20,118,318,-43" GroupName="MCSites" Visibility="Hidden">
Radio Button Description
</RadioButton>

Issue to Change button value dynamically in wpf

<Grid x:Name="LayoutRoot">
<Button x:Name="btn_num" Width="51" Margin="318.849,158,262.15,0" Height="45" VerticalAlignment="Top" d:LayoutOverrides="HorizontalMargin">
<Grid Height="38.166" Width="44.833">
<Label x:Name="lbl_2" Content="2" Margin="4.483,-2.042,7,-1.626" FontSize="11.333"/>
<Label x:Name="lbl_1" Content="1" Margin="4.483,0,7,-19.251" FontSize="11.333" Height="41.834" VerticalAlignment="Bottom"/>
<Label x:Name="lbl_3" Content="3" Margin="0,8.083,-15,-11.751" FontSize="11.333" HorizontalAlignment="Right" Width="33.35" Foreground="Black"/>
</Grid>
</Button>
<Button x:Name="btn_a" Content="A" HorizontalAlignment="Left" Margin="225.333,158,0,0" Width="55" Foreground="Black" Height="45" VerticalAlignment="Top" Click="btn_alt_Click" />
</Grid>
It's design will be like this
public partial class button : Window
{
static int _AClick = 0;
public button()
{
this.InitializeComponent();
}
private void btn_alt_Click(object sender, RoutedEventArgs e)
{
if (_AClick == 0)
{
_AClick = 1;
Fill();
}
else
{
btn_num.Content = "";
_AClick = 0;
}
}
public void Fill()
{
btn_num.Content = "3";
}
}
The result after window loaded
If i click A button first time. The result will be like this
If I click A button second time. The result will be like this
when I click A button second time. I need the result like below. what should I do for that.
There are a lot of ways available in WPF to achieve this. One way to do this is to have two ControlTemplates (one having all three numbers and other having just one number) and then set the template of your button in code -
<Grid x:Name="LayoutRoot">
<Grid.Resources>
<ControlTemplate
x:Key="threeNumberTemplate"
TargetType="{x:Type Button}">
<Grid Height="38.166" Width="44.833">
<Label x:Name="lbl_2" Content="2" Margin="4.483,-2.042,7,-1.626" FontSize="11.333"/>
<Label x:Name="lbl_1" Content="1" Margin="4.483,0,7,-19.251" FontSize="11.333" Height="41.834" VerticalAlignment="Bottom"/>
<Label x:Name="lbl_3" Content="3" Margin="0,8.083,-15,-11.751" FontSize="11.333" HorizontalAlignment="Right" Width="33.35" Foreground="Black"/>
</Grid>
</ControlTemplate>
<ControlTemplate
x:Key="oneNumberTemplate"
TargetType="{x:Type Button}">
<Label x:Name="lbl_3" Content="3" FontSize="11.333"/>
</ControlTemplate>
</Grid.Resources>
<Button x:Name="btn_num" Width="51" Margin="318.849,158,262.15,0" Height="45" VerticalAlignment="Top" Template="{StaticResource threeNumberTemplate}"></Button>
<Button x:Name="btn_a" Content="A" HorizontalAlignment="Left" Margin="225.333,158,0,0" Width="55" Foreground="Black" Height="45" VerticalAlignment="Top" Click="btn_alt_Click" />
</Grid>
Code behind -
private void btn_alt_Click(object sender, RoutedEventArgs e)
{
if (_AClick == 0)
{
_AClick = 1;
btn_num.Template = FindResource("oneNumberTemplate") as ControlTemplate;
}
else
{
btn_num.Template = FindResource("threeNumberTemplate") as ControlTemplate;
_AClick = 0;
}
}
Same can be achieved through triggers by making _AClick as DependecyProperty and using it's value to swap templates in triggers.
Another approach is to have two Buttons and hide/show them based on the _AClick value in code.
You can create three DataTemplate and use DataTemplateSelector class to load the corresponding data template on run time.
MSDN - DataTemplateSelector

WPF Treeview delete operation [duplicate]

This question already has answers here:
What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?
(5 answers)
Closed 1 year ago.
I am working on WPF TreeViews. I am able to add the new Items under tree, but I am not able to delete them from the list. In my code I am trying to get the index of the selected tree item and trying to Remove it. But the code is returning Index "-1". This results in an ArgumentOutOfRangeException.
Please help to fix this.
<Window x:Class="MyTreeStructure.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>
<Button Content="ADD" Height="23" HorizontalAlignment="Left" Margin="211,50,0,0"
Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<TreeView Height="200" HorizontalAlignment="Left" Margin="27,12,0,0" Name="treeView1"
VerticalAlignment="Top" Width="120" >
<TreeViewItem Name="Parent" Header="My Tree Content">
</TreeViewItem>
</TreeView>
<TextBox Height="23" HorizontalAlignment="Left" Margin="211,12,0,0" Name="textBox1"
VerticalAlignment="Top" Width="120" />
<Button Content="Delete" Height="23" HorizontalAlignment="Left" Margin="211,79,0,0"
Name="button2" VerticalAlignment="Top" Width="75" Click="button2_Click" />
</Grid>
</Window>
namespace MyTreeStructure
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
TreeViewItem temp = new TreeViewItem();
temp.Header = textBox1.Text;
Parent.Items.Add(temp);
}
private void button2_Click(object sender, RoutedEventArgs e)
{
textBox1.Text = treeView1.SelectedItem.ToString();
Parent.Items.RemoveAt(treeView1.Items.IndexOf(treeView1.SelectedItem));
**// Here I am getting exception. What should be the code here ??**
}
}
}
below line is having the problem
treeView1.Items.IndexOf(treeView1.SelectedItem))
Since treeview1 is only having one node 'Parent' , rest of the node which you have added is in the node called 'Parent'.
So if you trying to get the index for a node in treeView1.Items it will return -1 except for the node called 'Parent' for which it will return 0.
so you nned to modify the code for removing a node as below.
private void button2_Click(object sender, RoutedEventArgs e)
{
textBox1.Text = treeView1.SelectedItem.ToString();
int index = treeView1.Items.IndexOf(treeView1.SelectedItem));
if(index < 0)
{
index = Parent.Items.IndexOf(treeView1.SelectedItem));
}
if(index > 0)
{
Parent.Items.RemoveAt(index);
}
}
I am not familiar with WPF but in WinForms your approach will cause errors. The first one could be a result of the internal numeration of items. It is like this:
0
-0
-1
-2
1
-0
-0
-1
-1 ...
Another stumbling stone is that IndexOf returns -1 (as you mentioned) if the item was not found. You have to check if the value is -1 first, then navigate to the correct Sublist in Treeview.Nodes.Nodes... and finally call RemoveAt().
I Hope this was helpful
Patrick
Here's my two cents worth. This code is working on my machine.
TreeViewItem t;
private void button2_Click(object sender, RoutedEventArgs e)
{
// Delete the node
Parent.Items.RemoveAt(Parent.Items.IndexOf(t));
}
private void treeView1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
// Get the selected node
t = (TreeViewItem)(((TreeView)e.Source).SelectedItem);
}
<Grid>
<TextBox Height="23" HorizontalAlignment="Left" Margin="8,14,0,0" Name="textBox1" VerticalAlignment="Top" Width="127" />
<Button Height="23" Margin="140,14,0,0" Name="button1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="76" Click="button1_Click">Add Item</Button>
<Button Height="23" Margin="226,14,124,0" Name="DeleteButton" VerticalAlignment="Top" Click="DeleteButton_Click">Delete Item</Button>
<TreeView Margin="10,100,0,13" Name="TreeView1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="194" Height="200">
<TreeViewItem x:Name="Parent" Header="Cold Drinks">
<TreeViewItem Header="Coke"></TreeViewItem>
<TreeViewItem Header="Pepsi"></TreeViewItem>
<TreeViewItem Header="Orange Juice"></TreeViewItem>
<TreeViewItem Header="Milk"></TreeViewItem>
<TreeViewItem Header="Iced Tea"></TreeViewItem>
<TreeViewItem Header="Mango Shake"></TreeViewItem>
</TreeViewItem>
</TreeView>
</Grid>
private void button1_Click(object sender, RoutedEventArgs e)
{
TreeViewItem newChild = new TreeViewItem();
newChild.Header = textBox1.Text;
Parent.Items.Add(newChild);
}
private void DeleteButton_Click(object sender, RoutedEventArgs e)
{
int index = TreeView1.Items.IndexOf(TreeView1.SelectedItem);
if (index < 0)
{
index = Parent.Items.IndexOf(TreeView1.SelectedItem);
}
if (index >= 0 && ((System.Windows.Controls.TreeViewItem)TreeView1.SelectedItem).Name.Contains("Parent"))
{
TreeView1.Items.RemoveAt(index);
}
else if (index >= 0)
{
Parent.Items.RemoveAt(index);
}
}

Categories