Textbox inside listbox selecteditem.. how modify textbox content? - wpf

I have a listbox for inventory. When I select an item it shows a couple of controls to edit the volume or amount of items. like this:
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal" >
<Label Content="Edit Volume:"/>
<Button Click="bPlus_Click2" Content="+" Height="29" Margin="10,0,0,0" Name="bPlus" Width="29" />
<TextBox FontSize="16" Height="29" HorizontalContentAlignment="Center" IsReadOnly="True" Name="tNum2" Text="0" VerticalContentAlignment="Center" Width="44" />
<Button Click="bMinus_Click2" Content="-" Height="29" Name="bMinus" Width="29" />
<Button Content="OK!"/>
<StackPanel.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}}" Value="False">
<Setter Property="StackPanel.Visibility" Value="Collapsed"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
</StackPanel>
Now I need the PLUS and MINUS buttons to edit the content of the textbox.. how can i do it??
I FOUND THE WAY!!
THIS IS WHAT I HAVE:
<Window.Resources>
<DataTemplate x:Key="dtInventory">
<Border Name="itemBorder" BorderBrush="#FFEBE476" BorderThickness="2" Padding="10" Margin="2" Background="#FF5AB11D">
<StackPanel x:Name="sp1">
<StackPanel Orientation="Horizontal" x:Name="spsp1">
<StackPanel Width="60">
<TextBlock Text="DME Item: "/>
</StackPanel>
<StackPanel Width="205" x:Name="spsp2">
<TextBlock Text="{Binding Path=Name}"/>
</StackPanel>
<StackPanel Width="60" x:Name="spsp3">
<TextBlock Text="Volume: "/>
</StackPanel>
<StackPanel Width="30" x:Name="spsp4">
<TextBlock Text="{Binding Path=Volume}"/>
</StackPanel>
</StackPanel>
<StackPanel x:Name="sp2" HorizontalAlignment="Right" Orientation="Horizontal" >
<Label Content="Edit Volume:" x:Name="l1"/>
<myext:IntegerUpDown x:Name="udVolume" Minimum="0" DefaultValue="0"/>
<Button Content="OK!" x:Name="bOk" Click="bOk_Click" />
<StackPanel.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}}" Value="False">
<Setter Property="StackPanel.Visibility" Value="Collapsed"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</Window.Resources>
Then the Listbox:
<ListBox Height="399" HorizontalAlignment="Left" Margin="462,61,0,0" Name="lInventory" VerticalAlignment="Top" Width="390" ItemsSource="{Binding}" ItemTemplate="{StaticResource dtInventory}">
And the .cs:
ListBoxItem selecteditem = lInventory.ItemContainerGenerator.ContainerFromIndex(int.Parse(lInventory.SelectedIndex.ToString())) as ListBoxItem;
if (selecteditem != null)
{
try
{
DataTemplate dt = selecteditem.ContentTemplate;
Border border = VisualTreeHelper.GetChild(selecteditem, 0) as Border;
ContentPresenter cp = border.Child as ContentPresenter;
StackPanel sp = dt.FindName("sp1", cp) as StackPanel;
IntegerUpDown updown = sp.FindName("udVolume") as IntegerUpDown;
if (updown.Value != 0)
{
Inventory.DMEItems dme = new Inventory.DMEItems();
dme.Volume = int.Parse(updown.Value.ToString());
dme.DMEInventoryItemID = int.Parse(lInventory.SelectedValue.ToString());
dme.UpdateItem();
UpdateInventory();
}
}
catch (Exception ex)
{ System.Windows.MessageBox.Show("ERROR: " + ex.Message, "Edit Volume" ,MessageBoxButton.OK, MessageBoxImage.Error); }
}
I hope it works for other people!

Unfortunately you can't do Mathematic oeprations in xaml out of the box.
But you could use a Numeric UpDown control (e.g. from the Extented WPF Toolkit)
Or you make your own UserControl where you have your two buttons and your textbox along with the functionality to count up/down.
Then use that control in your markup e.g.
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal" >
<Label Content="Edit Volume:"/>
<local:MyNumericUpDownControl/>
EDIT:
Here's a link on how to create your own numericupdown control

Related

Button within ListBox ItemTemplate not selecting item wpf mvvm

Hi i have the same problem as here Button within ListBox ItemTemplate not selecting item
And i know the reason why my button doesnt see selected item, it because listbox is called when MouseDown
and button is called on Click. But i dont know how to fix it
XAML
<ListBox Grid.Row="1" x:Name="ListViewProduct" Background="#FFf1f1f1" ItemsSource="{Binding Videos}" >
<ListBox.ItemTemplate>
<!-- FIX Ripple-->
<DataTemplate >
<Border Background="White" Name="border" Margin="50 10 50 10" Width="310" Height="360">
<StackPanel>
<Border Width="300" Height="300" CornerRadius="5" Margin="5">
<Border.Effect>
<DropShadowEffect ShadowDepth="5"/>
</Border.Effect>
<Border.Background>
<ImageBrush ImageSource="{Binding Image}"/>
</Border.Background>
</Border>
<Grid>
<StackPanel>
<TextBlock Margin="5" Text="{Binding Name}" FontSize="14" FontFamily="Franklin Gothic Medium" />
<TextBlock Margin="5 0" Text="{Binding User.Name}" FontSize="13" />
</StackPanel>
<Button HorizontalAlignment="Right" Margin="0 0 10 0"
Command="{Binding ElementName= ListViewProduct,Path=DataContext.DownloadPageCommand}"
CommandParameter="{Binding Path=SelectedItem , ElementName=ListViewProduct}">
<materialDesign:PackIcon Width="25" Height="25" Kind="Download" Foreground="White"/>
</Button>
</Grid>
</StackPanel>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<i:InvokeCommandAction Command="{Binding ElementName= ListViewProduct,Path=DataContext.ViewWatchingPageCommand}"
CommandParameter="{Binding Path=SelectedItem , ElementName=ListViewProduct}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
C#
private RelayCommandParametr _downloadpageCommand;
public RelayCommandParametr DownloadPageCommand
{
get
{
return _downloadpageCommand
?? (_downloadpageCommand = new RelayCommandParametr(
obj =>
{
SelectedVideo = obj as Video;
_navigationService.NavigateTo("Download",obj);
}));
}
}
private RelayCommandParametr _viewWatchingPageCommand;
public RelayCommandParametr ViewWatchingPageCommand
{
get
{
return _viewWatchingPageCommand
?? (_viewWatchingPageCommand = new RelayCommandParametr(
(obj) =>
{
SelectedVideo = obj as Video;
_navigationService.NavigateTo("VideoWatching",SelectedVideo);
}));
}
}
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
I find answer i just set selected item.

How to Increase the Height of Silverlight Datagrid Header

I am new to silver Light. How to Increase the Height of Silverlight Datagrid Header
I am using template column
Code as follows :
<sdk:DataGridTemplateColumn Header="Base Receipt">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<sdk:Label Margin="5,0,5,0" Height="25" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</sdk:DataGridTemplateColumn>
You can use HeaderStyle :
<sdk:DataGridTemplateColumn Header="Base Receipt">
<sdk:DataGridTemplateColumn.HeaderStyle>
<Style TargetType="sdk:DataGridColumnHeader">
<Setter Property="Height" Value="50" />
</Style>
</sdk:DataGridTemplateColumn.HeaderStyle>
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<sdk:Label Margin="5,0,5,0" Height="25" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</sdk:DataGridTemplateColumn>

Can we have buttons in a validation template, and how can we bind it to the ViewModel method?

Requirement:
Need to display an error message when the user types a forlder name that doesn't exist as shown below:
Problem: I am able to display the UI but not able to call a method in the view model when the user clicks on the button "CreateNew"
View Model Code:
public string this[string columnName]
{
get { return "The entered folder name doesn't exist."; }
}
RelayCommand createNewFolder;
public RelayCommand CreateNewFolder
{
get
{
if (createNewFolder == null)
createNewFolder = new RelayCommand(param => this.OnCreateNewFolder());
return createNewFolder;
}
}
public void OnCreateNewFolder()
{
MessageBox.Show("CreateNewFolder");
}
RelayCommand.cs can be downloaded at: http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=mag200902MVVM&DownloadId=4357
Xaml Code:
<Window.Resources>
<ControlTemplate x:Key="validationTemplate">
<DockPanel LastChildFill="True">
<Border Margin="5,5,0,0" DockPanel.Dock="Bottom" Background="Red">
<StackPanel>
<TextBlock Name="ErrorText" Foreground="White" Background="Red"
FontSize="12" Padding="2" FontFamily="Trebuchet MS"
TextWrapping="Wrap"
Text="{Binding [0].ErrorContent}" ></TextBlock>
<StackPanel Margin="0" Orientation="Horizontal">
<Button Content="Create New" Command="{Binding Path=CreateNewFolder}" Margin="10" Padding="5"></Button>
<Button Content="Cancel" Margin="10" Padding="5" ></Button>
</StackPanel>
</StackPanel>
</Border>
<AdornedElementPlaceholder Name="ErrorTextBox" />
</DockPanel>
</ControlTemplate>
<Style x:Key="ValidationStyle" TargetType="{x:Type ComboBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BitmapEffect">
<Setter.Value>
<BitmapEffectGroup>
<OuterGlowBitmapEffect GlowColor="Red" GlowSize="3" Noise="0.6"></OuterGlowBitmapEffect>
</BitmapEffectGroup>
</Setter.Value>
</Setter>
<Setter Property="DataContext"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},Path=DataContext}">
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<AdornerDecorator >
<ComboBox IsEditable="True" FontSize="11" Margin="10" Width="250"
VerticalAlignment="Center"
Text="{Binding Path=StrText, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"
Validation.ErrorTemplate="{StaticResource validationTemplate}"
Style="{StaticResource ValidationStyle}"></ComboBox>
</AdornerDecorator>
</Grid>
Please note that i set the DataContext property in the style:
<Setter Property="DataContext" Value="{Binding RelativeSource={x:Static
RelativeSource.Self},Path=DataContext}">
</Setter>
Please let me know how to bind the method to a button in the validation template.
You could reference the DataContext for the AdornerDecorators Child in the Binding. I think something like this will work
<Button Content="Create New"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type AdornerDecorator}},
Path=Child.DataContext.CreateNewFolder}"
Margin="10" Padding="5"></Button>
This line looks suspicious:
createNewFolder = new RelayCommand(param => this.OnCreateNewFolder());
Maybe you should replace it by:
createNewFolder = new RelayCommand(OnCreateNewFolder);

Changing ContentTemplate based on ListBox selection

I have a Listbox and a Border in a StackPanel similar to the following:
<StackPanel Orientation="Horizontal">
<ListBox>
<ListBoxItem Content="People"/>
<ListBoxItem Content="Animals"/>
<ListBoxItem Content="Cars"/>
</ListBox>
<Border Width="200>
<ContentPresenter/>
</Border>
</StackPanel>
When selecting an item in the listbox I would like to change the content in the ContentPresenter accordingly e.g. selecting People would change the template to display a series of input fields related to people where as selecting Animals would display a series of fields related to Animals etc. - the behavior of this would be akin to a TabControl.
I think I can achieve this with a DataTrigger which changes the DataTemplate in the Border but I'm not sure how to achieve this.
Any pointers?
Thanks
You can toggle the ContentTemplate using a DataTrigger as follows.
Note, that I am binding an ObservableCollection to a simple object (Thing) with one property called Name, and am I binding the Content of the ContentControl to the SelectedItem in the ListBox using a ViewModel.
<Grid>
<Grid.Resources>
<local:MultiValueConverter x:Key="con" />
<DataTemplate x:Key="PeopleTemplate">
<StackPanel Orientation="Horizontal">
<Label Margin="0,0,5,0" Content="People Name" HorizontalAlignment="Left" Grid.Column="0" />
<TextBox Grid.Column="1" Width="100" Height="25"></TextBox>
<Button Content="OK" Grid.Column="2" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="AnimalsTemplate">
<StackPanel Orientation="Horizontal">
<Label Margin="0,0,5,0" Content="Animal Name" HorizontalAlignment="Left" Grid.Column="0" />
<TextBox Grid.Column="1" Width="100" Height="25"></TextBox>
<Button Content="OK" Grid.Column="2" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="CarsTemplate">
<StackPanel Orientation="Horizontal">
<Label Margin="0,0,5,0" Content="Car Name" HorizontalAlignment="Left" Grid.Column="0" />
<TextBox Grid.Column="1" Width="100" Height="25"></TextBox>
<Button Content="OK" Grid.Column="2" />
</StackPanel>
</DataTemplate>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<ListBox ItemsSource="{Binding Things}" SelectedItem="{Binding SelectedThing}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0" Orientation="Horizontal">
<TextBlock Padding="5" Text="{Binding Name}" Margin="0"></TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Border Width="200">
<ContentControl Content="{Binding SelectedThing}">
<ContentControl.ContentTemplate>
<DataTemplate>
<ContentControl Name="cc"
Content="{Binding}"
ContentTemplate="{StaticResource PeopleTemplate}" />
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=Name}" Value="People">
<Setter TargetName="cc"
Property="ContentTemplate"
Value="{StaticResource PeopleTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Name}" Value="Animals">
<Setter TargetName="cc"
Property="ContentTemplate"
Value="{StaticResource AnimalsTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=Name}" Value="Cars">
<Setter TargetName="cc"
Property="ContentTemplate"
Value="{StaticResource CarsTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</Border>
</StackPanel>
<Grid>
Here is the Thing class:
public class Thing
{
public Thing(String name)
{
this.Name = name;
}
public String Name { get; set; }
public static ObservableCollection<Thing> GetThingList()
{
return new ObservableCollection<Thing>(new Thing[3] {
new Thing("People"),
new Thing("Animals"),
new Thing("Cars")
});
}
}

How do I add a close button to the header of a ContentPane

How do I add a close button to the header of a ContentPane? Please explain it with an example.
<DataTemplate x:Key="tabItemHeaderWithClose">
<DockPanel x:Name="pnl">
<Button x:Name="closeBtn" DockPanel.Dock="Right"
Visibility="Collapsed"
Margin="3,3,0,3" Width="14" VerticalAlignment="Top"
Command="{x:Static DockManager:ContentPaneCommands.Close}"
CommandTarget="{Binding Path=Pane,RelativeSource={RelativeSource AncestorType={x:Type DockManager:PaneTabItem}}}"
Style="{DynamicResource {x:Static DockManager:TabGroupPane.DocumentCloseButtonStyleKey}}" />
<TextBlock Text="{Binding}" />
</DockPanel>
<DataTemplate.Triggers>
<Trigger Property="DockManager:XamDockManager.PaneLocation"
Value="Document">
<Setter TargetName="closeBtn" Property="Visibility" Value="Visible"/>
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
XAML:
<ContentControl Name="contentControl1" >
<StackPanel>
<StackPanel Name="headerPanel" VerticalAlignment="Top" >
<Grid>
<Label>Header text</Label>
<Button Name="closeButton" Height="20" Width="20" HorizontalAlignment="Right" Click="closeButton_Click">X</Button>
</Grid>
</StackPanel>
<StackPanel Name="contentPanel" VerticalAlignment="Stretch" >
<Label>Hello</Label>
</StackPanel>
</StackPanel>
</ContentControl>
C#:
private void closeButton_Click(object sender, RoutedEventArgs e)
{
contentControl1.Visibility = Visibility.Hidden;
}

Resources