I am trying to add a ToolTip on my TextBlock. After some research this is how I added it on UWP
xaml:
<ListView x:Name="flyList" BorderThickness="0" ItemsSource="{Binding}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Border BorderThickness="0,0,0,1" BorderBrush="#FF7C7C7C">
<TextBlock Text="{Binding}" Tapped="TextBlock_Tapped">
<ToolTipService.ToolTip>
<ToolTip Name="tip1" Content="Click to copy signal to clipboard."/>
</ToolTipService.ToolTip>
</TextBlock>
</Border>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
How can I set the ToolTip's content? Or better how can I even access it?
I want to access it on TextBlock's tapped event.
private void TextBlock_Tapped(object sender, TappedRoutedEventArgs e)
{
/*
var send = sender as TextBlock;
var dataPackage = new DataPackage { RequestedOperation = DataPackageOperation.Copy };
dataPackage.SetText(send.Text);
Clipboard.SetContent(dataPackage);
*/
}
Try this:
private void TextBlock_Tapped(object sender, TappedRoutedEventArgs e)
{
var txt = sender as TextBlock;
ToolTip tt = ToolTipService.GetToolTip(txt) as ToolTip;
tt.Content = "...";
}
And please tag your questions properly. UWP is not the same thing as WPF.
Related
I wish to get all the files in a certain folder and display them in a ListView in WPF.
I have the following:
XAML
<ListBox Name="MyListBox"">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code Behind
string location = AppDomain.CurrentDomain.BaseDirectory + "MyApp\\Documents\\";
string[] myFiles = Directory.GetFiles(location, "*.pdf")
.Select(path => Path.GetFileName(path).Replace(".pdf",""))
.ToArray();
MyListBox.ItemsSource = myFiles;
This lists all the files in a my list box.
What I wish to do is to add a CLick handler for each item in the list and call a function and pass in the text of the item clicked.
How can I do this?
If it's not a MVVM then you can define a button with handler which exist in code base. On each button click the same handler will be executed. Now question comes how to inject the file Name. So for that you can add the file Name in Tag object of button which can be read in code behind by handler for further processing.
XAML
<ListBox Name="MyListBox"">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding}" />
<Button Click="Open_Click" Tag="{Binding}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code Behind Handler
void Open_Click(object sender, EventArgs e)
{
var button = sender as Button;
var filename = Convert.ToString(button.Tag); // File Name
}
Just add the event in the ListBox:
<ListBox Name="MyListBox" MouseDoubleClick="Open_Click">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
void Open_Click(object sender, EventArgs e) {
ListBox listbox = sender as ListBox;
string filename = listbox.SelectedItem.ToString();
}
In my Windows/Windows Phone Universal App, I have ListView with a MenuFlyout in my XAML layout. The ListView includes a list of people. Tapping on a list item reveals the flyout with options to email or call the person. Right now I am using the Tag property of the MenuFlyoutItem to hold the email address and phone number, but I also want to be able to get the name of the person so I can send that when I open the email composer or phone dialer.
I am using the Tag element to store the basic information, but I want to access the name. How do I do this? Using extra properties? Somehow accessing the data binding of the parent object?
XAML:
<ListView
x:Name="itemPositions"
AutomationProperties.AutomationId="ItemListView"
AutomationProperties.Name="Items In Group"
TabIndex="1"
Grid.Row="1"
ItemsSource="{Binding Positions}"
SelectionMode="None"
IsSwipeEnabled="false"
Margin="0,0,0,0">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Tapped="Grid_Tapped">
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem IsEnabled="{Binding IsFilled}" Tag="{Binding Email}" x:Name="sendEmail" Text="email" Click="sendEmail_Click" />
<MenuFlyoutItem IsEnabled="{Binding IsFilled}" Tag="{Binding Phone}" x:Name="sendCall" Text="call" Click="sendCall_Click" />
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" Visibility="{Binding IsVerified, Converter={StaticResource BoolToInvisible}}" Margin="0,0,0,5" Background="Firebrick" Width="10" Height="70" />
<Border Visibility="{Binding Required, Converter={StaticResource BoolToVisible}}">
<Border Grid.Column="0" Visibility="{Binding IsFilled, Converter={StaticResource BoolToInvisible}}" Margin="0,0,0,5" Background="Gold" Width="10" Height="70" />
</Border>
<StackPanel Margin="10,0,0,10" Grid.Column="1">
<TextBlock Text="{Binding PositionName}" Style="{ThemeResource ListViewItemTextBlockStyle}"/>
<TextBlock Text="{Binding DisplayName}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" />
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
C#:
private void Grid_Tapped(object sender, TappedRoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element != null) FlyoutBase.ShowAttachedFlyout(element);
}
private async void sendEmail_Click(object sender, RoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
Windows.ApplicationModel.Email.EmailMessage mail = new Windows.ApplicationModel.Email.EmailMessage();
mail.Subject = "Leadsheet Position Assignment";
mail.To.Add(new Windows.ApplicationModel.Email.EmailRecipient(element.Tag.ToString()));
await Windows.ApplicationModel.Email.EmailManager.ShowComposeNewEmailAsync(mail);
}
private void sendCall_Click(object sender, RoutedEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
Windows.ApplicationModel.Calls.PhoneCallManager.ShowPhoneCallUI(element.Tag.ToString(), "");
}
I thin you should be able to do this for example by checking the DataContext of clicked Grid or MenuItem:
private void Grid_Tapped(object sender, TappedRoutedEventArgs e)
{
Item yourItem = (sender as Grid).DataContext as Item;
FrameworkElement element = sender as FrameworkElement;
if (element != null) FlyoutBase.ShowAttachedFlyout(element);
}
// you can also do the same in your menu items:
private async void sendEmail_Click(object sender, RoutedEventArgs e)
{
Item yourItem = (sender as MenuFlyoutItem).DataContext as Item;
FrameworkElement element = sender as FrameworkElement;
Windows.ApplicationModel.Email.EmailMessage mail = new Windows.ApplicationModel.Email.EmailMessage();
mail.Subject = "Leadsheet Position Assignment";
mail.To.Add(new Windows.ApplicationModel.Email.EmailRecipient(element.Tag.ToString()));
await Windows.ApplicationModel.Email.EmailManager.ShowComposeNewEmailAsync(mail);
}
Item above is your ItemClass which you use in Positions set as ItemsSource. Once you have the clicked item, the rest should be easy. With this you also no longer need to bind in Tag property.
I've got some images in a ListBox. When the user clicks one image, I'd like to open a new window (ImageWindow) and show the clicked image in the new window. I've added already a new XAML-file and a eventhandler. This is what I got:
MainWindow:
<ListBox Name="MainListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel HorizontalAlignment="Center">
<Image Source="{Binding}" MouseDown="Image_MouseDown"></Image>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
/*========================================================================*/
private void Image_MouseDown(object sender, MouseButtonEventArgs e)
{
ImageWindow imageWindow = new ImageWindow();
//Pass image
imageWindow.Show();
}
ImageWindow:
<ListBox Name="ImageListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel HorizontalAlignment="Center">
<Image Source="{Binding}"></Image>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
How do I pass the clicked image?
See example (click on the image)
Just copy, past and tune this code so it fits your varnames:
private void ListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e) //Varname
{
ImageWindow imageWindow = new ImageWindow { Owner = this };
foreach (var item in ListBox.Items) //Varname
{
imageWindow.ListBox.Items.Add(item);//Varname
}
imageWindow.SetSelectedImageIndex = ListBox.SelectedIndex; //Varname + save the index of the selected item and pass it to ImageWindow
imageWindow.Show();
}
ImageWindow:
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Application.Current.MainWindow.WindowState = WindowState.Normal;
ListBoxItem lbi = (ListBoxItem)ImageListBox.ItemContainerGenerator.ContainerFromIndex(SetSelectedImageIndex); //Get with the index the befor selected item
lbi.Focus(); //Set the focus on it
}
You can start with something like this:
<Grid
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions">
<Popup x:Name="popup" PlacementTarget="{Binding ElementName=imageList}">
<Image Source="{Binding PlacementTarget.SelectedItem , ElementName=popup}"/>
</Popup>
<ListView x:Name="imageList" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<ei:ChangePropertyAction PropertyName="IsOpen"
TargetName="{Binding ElementName=popup}" Value="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListView>
</Grid>
Add references to Microsoft.Expression.Interactions and to System.Windows.Interactivity to get it work.
I'm trying to create an ItemTemplate for a ListBox programmatically but it doesn't work. I know in XAML I can have something like:
<ListBox x:Name="listbox" BorderThickness="0" Margin="6" Height="400">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Margin="0" Background="Red" Foreground="White" FontSize="18" Text="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But when I'm trying to have the above result programmatically I face a problem which is binding the TextBox.TextProperty:
var textblock = new FrameworkElementFactory(typeof(TextBlock));
// Setting some properties
textblock.SetValue(TextBlock.TextProperty, ??);
var template = new ControlTemplate(typeof(ListBoxItem));
template.VisualTree = textblock;
Please help me on this issue. I couldn't find anything on the web about it.
Thanks in advance.
Try use dot . in Binding, this is the equivalent of {Binding}.
Example:
XAML
<Window x:Class="MyNamespace.MainWindow"
...
Loaded="Window_Loaded">
<ListBox Name="MyListBox" ... />
</Window>
Code-behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
var textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));
textBlockFactory.SetValue(TextBlock.TextProperty, new Binding(".")); // Here
textBlockFactory.SetValue(TextBlock.BackgroundProperty, Brushes.Red);
textBlockFactory.SetValue(TextBlock.ForegroundProperty, Brushes.Wheat);
textBlockFactory.SetValue(TextBlock.FontSizeProperty, 18.0);
var template = new DataTemplate();
template.VisualTree = textBlockFactory;
MyListBox.ItemTemplate = template;
}
}
Try this, by binding the "listbox" with ItemsSource and specify the datatemplate below like if you want to bind name then just write {Binding Name}
<ListBox x:Name="listbox" BorderThickness="0" Margin="6" Height="400" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Margin="0" Background="Red" Foreground="White" FontSize="18" Text="{Binding Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I set a DataTemplate for my LongListSelector:
<ctl:LongListSelector Loaded="listbox_Loaded" Name="listbox" SelectionChanged="listbox_selectionChanged">
<ctl:LongListSelector.ItemTemplate>
<DataTemplate>
<Border Background="Gray" MouseLeftButtonDown="listbox_itemClicked">
<TextBlock Text="{Binding}" TextWrapping="Wrap" Width="350"/>
</Border>
</DataTemplate>
</ctl:LongListSelector.ItemTemplate>
</ctl:LongListSelector>
After some actions I changed a view of some items from code and now need to restore this DataTemplate, that described above. How to do this from code?
There are some handlers. The first one gets value from TextBlock, the second one turns the selected item to red. When I select another item I should return the previous to gray color. It seems like attempt to restore DataTemplate doesn't work.
private void listbox_selectionChanged(object sender, SelectionChangedEventArgs e)
{
var lb = (LongListSelector)sender;
var lbi = lb.SelectedItem.ToString();
lb.ItemTemplate = Resources["ItemTemplateLongListSelector"] as DataTemplate;
var categoryCode = CategoryCodes.ElementAt(CategoryNames.IndexOf(lbi));
addedItem.Category = categoryCode;
}
private void listbox_itemClicked(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
var border = (Border)sender;
var borderBrush = new SolidColorBrush();
borderBrush.Color = Color.FromArgb(255, 255, 0, 0);
border.Background = borderBrush;
}
Thank You!
You can make a Resource:
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="ItemTemplateLongListSelector">
<Border Background="Gray"
MouseLeftButtonDown="listbox_itemClicked">
<TextBlock Text="{Binding}"
TextWrapping="Wrap"
Width="350" />
</Border>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
Bind DataTemplate to ItemTemplate:
<phone:LongListSelector Loaded="listbox_Loaded"
Name="LongListSelector"
SelectionChanged="listbox_selectionChanged"
ItemTemplate="{StaticResource ItemTemplateLongListSelector}" />
To set standard DataTemplate in code behind you can do the following:
LongListSelector.ItemTemplate = Application.Current.Resources["ItemTemplateLongListSelector"] as DataTemplate;
OR
LongListSelector.ItemTemplate = Resources["ItemTemplateLongListSelector"] as DataTemplate;
I hope this will help!