XAML communication betwen listbox items with template? - c#

I am trying to solve problem with communication between items in listbox with template. Lets say i have template:
<DataTemplate x:Key="Template">
<StackPanel HorizontalAlignment="Stretch">
<TextBox Name="A" FontSize="17" Margin="5,5,5,1"></TextBox>
<TextBox Name="B" FontSize="15" Margin="5,0,5,1"></TextBox>
</StackPanel>
</DataTemplate>
And when i type data on Textbox B and press ENTER i call method that sends typed text to Textbox A. Problem is how i can create such keydown metod for template items in listbox item and what if i will heve more than one item?

Why don't you try binding like this
<DataTemplate x:Key="Template">
<StackPanel HorizontalAlignment="Stretch">
<TextBox Name="A" Text="{Binding Text, ElementName=B}" FontSize="17" Margin="5,5,5,1" />
<TextBox Name="B" FontSize="15" Margin="5,0,5,1" />
</StackPanel>
</DataTemplate>

Lets say I got it. But its kind of problematic one. Its windows 8 store app and I think I cant process with that problem like in WPF. Thats how i did it:
var parent = ((TextBox)sender).Parent;
var child = VisualTreeHelper.GetChild(parent, 1);
TextBox text = (TextBox)child;
text.Text += Client.Settings.Account + ": " + ((TextBox)sender).Text + "\n";
((TextBox)sender).Text = string.Empty;
And that one problem made another two:
When I change my template everything is going to be broken.
Lets say i want to get to the specific TextBox A in the specific Item I have no idea how to get to it. I mean i have IncomingMessage method where i need to find the item that is my contact and place his message to his TextBox A.

Related

Change field of a TextBox with Button click at the same index in Data Binded List View

I have a ListView with a collection as ItemsSource.
<ListView x:Name="lvBT" Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}"
ItemsSource="{x:Bind ViewModel.CurrentPoste.TableauxBT}" Margin="0,0,0,12"
IsEnabled="{x:Bind ViewModel.CurrentPoste.BtEdition, Mode=TwoWay}"
SelectionMode="None">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:BT">
[...]
<TextBox x:Name="tbNumSerieBT" HorizontalAlignment="Stretch" Margin="12,32,16,0" Text="{x:Bind NumSerie, Mode=TwoWay}" VerticalAlignment="Top" Grid.Column="3" FontSize="16" Grid.ColumnSpan="2"/>
<Button x:Name="bScannerBT" Grid.Column="5" HorizontalAlignment="Stretch" Margin="12,32,15,0" VerticalAlignment="Top" Content="Scanner tabeau BT" FontSize="14" Click="BScannerBT_Click"/>
[...]
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
tableauxBT is representing a collection of BT objects and for each object in that collection I'm creating a DataTemplate, like basic data binding.
When I click on the Button in that template I'm scanning a barcode with a BarcodeScanner and want to put the return value in the TextBox field.
For each button of each different BT item I want to scan a different barcode but the problem is that I don't know how to get the index of the Button that was clicked to put the value in the right TextBox.
So how can I do to get the index of the clicked Button to put the value in the TextBox at the same index ?
You can get the index of the clicked button using the "BScannerBT_Click" method.
public BScannerBT_Click(object sender, EventArgs e)
{
var myClickedButton = (Button)sender; //this object hold all information you need.
//You can reach the button's dataContext and change the value you want to.
var buttonDataContext = myClickedButton.DataContext.
//now you have the ViewModel (buttonDataContext) associated with the 'NumSerie'
}
I hope it helps you.

Create an Element after a specific Element in a StackPanel

I need to create a XAML textbox immediately after another textbox using code-behind. Maybe something like this:
Before
<StackPanel>
<TextBox Name="TextBox1"/>
<TextBox Name="TextBox2"/>
<TextBox Name="TextBox3"/>
</StackPanel>
After
<StackPanel>
<TextBox Name="TextBox1"/>
<TextBox Name="TextBox2"/>
<TextBox Name="InsertedTextBox"/> <!--This textbox was inserted after 'TextBox2'-->
<TextBox Name="TextBox3"/>
</StackPanel>
I have the name of the textbox I wish to insert the other textbox after. May I know how I can insert a textbox after another textbox which I know the name of?
Note: I am programming for Universal Windows.
Thanks in advance.
You need to name the StackPanel to reference it in code, and you need the index of the preceding TextBox:
var index = this.stackPanel1.Children.IndexOf(TextBox2);
this.stackPanel1.Children.Insert(index + 1, new TextBox { Name = "InsertedTextBox" });
You could try this, note I've given the StackPanel a name.
// Where 2 is the index.
this.StackPanel1.Children.Insert(2, new TextBox());

Hold Event Longlistselector

Hej
I want to create a standard holdevent. When you hold an element, there would appear some options you could chose like a new list.
How do you create this, is it just simply done with a popup or is there a smarter way?
Extra
After finding the answer, see answer below, some nice info is:
Put the context creation inside the hold event.
Then you can change to different contextmenus depending on the item. You can get the item that was holded by the following
private void StackPanel_Hold(object sender, GestureEventArgs e)
{
ItemViewModel itemViewModel = (sender as StackPanel).DataContext as ItemViewModel;
string t = itemViewModel.LineOne;
}
And
<ListBox x:Name="MainListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Height="78" Hold="StackPanel_Hold">
<TextBlock Text="{Binding LineOne}" />
<TextBlock Text="{Binding LineTwo}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
A good link for easy implementation is also youtube link below, replicated here :
Youtube
A ContextMenu is one option..
http://blogs.msdn.com/b/msgulfcommunity/archive/2013/05/19/windows-phone-toolkit-context-menu-getting-selected-item-within-a-long-list-selector.aspx

wpf ListBox Control: simple GetSelectedValue / item-value

List box is not binded just a Combobox replacement (values are exposed)
Xaml
<ListBox SelectionChanged="LBX_AddTaskOptions_SelectionChanged" HorizontalAlignment="Left" Margin="19,29,0,0" Name="LBX_AddTaskOptions" VerticalAlignment="Top" Width="125" FontWeight="Bold" Background="Beige">
<ListBoxItem Background="Beige" FontWeight="Bold" v>
<StackPanel Orientation="Horizontal">
<TextBlock Text="internet"></TextBlock>
<Image Source="Images\IE_BlackRed.png" Height="30"></Image>
</StackPanel>
</ListBoxItem>
<ListBoxItem Background="Beige" FontWeight="Bold">
<StackPanel Orientation="Horizontal">
<TextBlock Text="localFolder"></TextBlock>
<Image Source="Images\Folder_Black.png" Height="30"></Image>
</StackPanel>
</ListBoxItem>
</ListBox>
CodeBehind
private void LBX_AddTaskOptions_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var SelItm = LBX_AddTaskOptions.SelectedItem.ToString();
MessageBox.Show(Sel);
}
i have searched for that question, though answers are only for complex issues
as i am fresh .net Developer, i know all methods to extract DDL text/value
i even made extentions , though couldn't figure how to do this simple value extraction
shouldn't it be simple ?
messageBox shows the name of control (:
This isn't quite the right approach for XAML. You don't want to list out the markup for each item -- instead, use an ItemTemplate to define how it should look, and use bindings to render the actual item:
<ListBox SelectionChanged="LBX_AddTaskOptions_SelectionChanged" Name="LBX_AddTaskOptions">
<ListBox.ItemTemplate>
<ListBoxItem Background="Beige" FontWeight="Bold" v>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" />
<Image Source="Images\IE_BlackRed.png" Height="30" />
</StackPanel>
</ListBoxItem>
</ListBox.ItemTemplate>
</ListBox>
Bind the ListBox ItemsSource to the model data itself (ie, the array of strings in this case). Now, eventually you'll probably want to use a view model, but you can also add the items from code behind on load:
string[] ListBoxItems = new string[] { "internet", "local folder" };
LBX_AddTaskOptions.ItemsSource = ListBoxItems;
This should result in SelectedValue giving you the correct value.
Footnote -- you could get the selected value using the markup you've written out in the question -- but it would be ugly and would defeat the whole purpose of XAML. You'd need to cast SelectedItem to a ListBoxItem, then get its child and cast that to a StackPanel, get its children, etc, you get the idea. And then, of course, if the markup changes at all, the code you just wrote is no longer valid.
The item that you are getting in your selected value is a ListBoxItem with a control inside it. If you want to extract the value like the text then you have to do this
private void LBX_AddTaskOptions_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var SelItm = LBX_AddTaskOptions.SelectedItem as ListBoxItem;
var StackPanel = SelItm.Content as StackPanel;
foreach (var child in StackPanel.Children)
{
if(child is TextBlock)
{
MessageBox.Show((child as TextBlock).Text);
}
}
}
You have to sort of dig into the control to get the actual text. There are a lot of ways to get the value but this is the pretty basic one.
Calling ToString() method will just convert the current object as a string which is a ListBoxItem.

WPF Hyperlink Child

I have a WPF Hyperlink that I am able to click and get its NavigateUri property just fine. However, I want to be able to bundle some additional information with the Hyperlink so I can process it in my event handler. This is how it looks right now:
<TextBlock Grid.Row="0">
<Hyperlink ToolTip="{Binding Path=Contact.ToolTipPersonalEmail}"
Name="ContactHyperlink" Foreground="#FF333333"
RequestNavigate="HandleContactEmailClicked"
NavigateUri="{Binding Path=Contact.Email}"
>
<TextBlock Text="{Binding Path=Contact.Fullname}" Width="Auto"
HorizontalAlignment="Stretch"
TextTrimming="CharacterEllipsis"/>
<TextBlock Text="{Binding Path=Data1}" Name="data1" Visibility="Collapsed" />
<TextBlock Text="{Binding Path=Data2}" Name="data2" Visibility="Collapsed" />
</Hyperlink>
</TextBlock>
Basically, in my event handler, I want to be able to access the data inside the two textblocks that have visibility = "Collapsed" (data1 and data2). I liken this to "hidden" data in an HTML form.
I tried messing with the "Inlines" property of Hyperlink but that's not working, and since this is inside a DataTemplate I can't access data1 and data2 by name in my code.
Any ideas?
Thanks.
creating textblocks to hold that data is somewhat... overkill. I'd go with one of these two options:
use databinding, to place a specific
object into the hyperlink, then to
get it back, all you need to do, is
access the DataContext of the
hyperlink,and it will provide you
the class which holds data1 and
data2
attach the object which
populates data1 and data2 into the
Hyperlink's TAG attribute
In your event handler you can do something like this:
ContentPresenter presenter = (ContentPresenter)sender.TemplatedParent;
DataTemplate template = presenter.ContentTemplate;
TextBlock textBlock = (TextBlock)template.FindName("data1", presenter);
Probably not the prettiest way, but it works for me.

Categories

Resources