I've defined a for a listbox item, and binded the text inside the tooltip to two properties of the object (name + description) but i have an issue that the text is being cut off
here is my tooltip:
<ToolTipService.ToolTip>
<StackPanel >
<StackPanel Orientation="Vertical">
<TextBlock FontSize="13">
<Bold>Name</Bold>
</TextBlock>
<TextBlock Text="{x:Bind name}"/>
</StackPanel>
<StackPanel Orientation="Vertical">
<TextBlock FontSize="13" TextWrapping="Wrap">
<Bold>Description</Bold>
</TextBlock>
<TextBlock Text="{x:Bind description}"/>
</StackPanel>
</StackPanel>
</ToolTipService.ToolTip>
Now the thing is, if i bind the tooltip to a method that returns the name + description (Which is how it was previously, but was super ugly) it does show all the text, it was like this:
<ToolTipService.ToolTip>
<TextBlock Text="{x:Bind Description}"/>
</ToolTipService.ToolTip>
But I needed to style it to make it look better, so i've tried to do what was posted above.
I've already tried setting the Width/Height to super large values, didn't do anything.
any ideas?
The tooltip template probably has a default maximum width, which cuts off the TextBlock. To solve this, just add TextWrapping attribute:
<TextBlock TextWrapping="Wrap" Text="{x:Bind description}"/>
Now the tooltip text will wrap on multiple lines as necessary
Related
I have got multiple TextBlocks whose Text is inserted through DynamicResource. They are all set to TextWrapping="Wrap". But inside those Text-strings I have words which are not allowed to be split up. Those words must be kept as a whole word.
With hardcoded Text in Xaml it's quite easy solved via a TextBlock inside a Textblock:
<TextBlock TextWrapping="Wrap">
Example text with wrap and <TextBlock TextWrapping="NoWrap" Text=" example text without wrap"/
</TextBlock>
But this solution does not work when Text the is inserted through DynamicResource, because the text is not getting parsed.
How can I combine nowrap and wrap inside a DynamicResource Text without splitting it into multiple TextBlocks one after another?
PS: I have now created an example to demonstrate the behavior I would like (green) and the failed attempts (red, orange, darkred) of solving it:
<StackPanel HorizontalAlignment="Center" Width="80" Orientation="Vertical">
<TextBlock TextWrapping="Wrap" Foreground="green">
bla1 bla2 bla3 bla4 <TextBlock TextWrapping="NoWrap" Text="Together(en)"/> bla5 bla6 longWordWhichShouldBreak
</TextBlock>
<TextBlock TextWrapping="Wrap" Foreground="red">
bla1 bla2 bla3 bla4 Together(en) bla5 bla6 longWordWhichShouldBreak
</TextBlock>
<TextBlock TextWrapping="Wrap" Foreground="orange">
bla1 bla2 bla3 bla4 Together(en) bla5 bla6 longWordWhichShouldBreak
</TextBlock>
<TextBlock TextWrapping="WrapWithOverflow" Foreground="DarkRed">
bla1 bla2 bla3 bla4 Together(en) bla5 bla6 longWordWhichShouldBreak
</TextBlock>
</StackPanel>
Use NO-BREAK SPACE in your dynamic text. For example:
<TextBlock TextWrapping="Wrap">
Example text with wrap and example text without wrap
</TextBlock>
You can replace space with this char in those parts that you need this behaviour:
Replace(" ", System.Convert.ToChar(160))
Have you considered using 'WrapWithOverflow' instead of 'Wrap'?
This will only break the line if a space appears.
You can then set the words that must appear together with dashes,e.g.-
'regular line and words-that-shouldn't-break'
You should use Run:
<TextBlock>
<Run Text={x:static SomeText} />
<Run Text={x:static SomeNoWrapText}
TextWrapping="NoWrap"/>
<Run Text={x:static SomeMoreText} />
</TextBlock>
It's a bit much for a comment, but also not a complete answer.
Lets translate your example piece of XAML from all the implicit contents to a full qualified structure.
Your simplified XAML, using the implicit content properties and so on:
<TextBlock TextWrapping="Wrap" Foreground="green">
bla1 bla2 bla3 bla4 <TextBlock TextWrapping="NoWrap" Text="Together(en)"/> bla5 bla6 longWordWhichShouldBreak
</TextBlock>
Equivalent actual structure:
<TextBlock TextWrapping="Wrap" Foreground="green">
<TextBlock.Inlines>
<Run Text="bla1 bla2 bla3 bla4 "/>
<InlineUIContainer>
<InlineUIContainer.Child>
<TextBlock TextWrapping="NoWrap" Text="Together(en)"/>
</InlineUIContainer.Child>
</InlineUIContainer>
<Run Text=" bla5 bla6 longWordWhichShouldBreak"/>
</TextBlock.Inlines>
</TextBlock>
This should give you some idea about the complexity of what you have in your XAML. You can't archieve the same result by simply setting the Text property.
Currently I can't answer how to solve this issue, since DynamicResource is not enough information to start transforming into above structure.
You may want to have a look at this question: Data binding the TextBlock.Inlines
Here is the XAML
<ListView x:Name="duplicateVarsInDepXMLListView" ItemsSource="{Binding}" HorizontalAlignment="Left" Height="100" Margin="362,360,0,0" VerticalAlignment="Top" Width="306">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name, StringFormat='Variable Name: {0}'}"/>
<TextBlock Text="{Binding Value,StringFormat='Value: {0}'}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
This xaml displays a List of collection with Variables Names and the values of a collection. We have something like Foreground property to change the colour of the binding characters or FontWeight to make it Bold.
However i only want to Change the font of the Label e.g. VariableName and not to the actual binding.
Is this possible to achieve? Any suggestions
You can use Run elements inside a TextBlock and apply different formatting to different runs. You can bind to the FontFamily property of the Run to dynamically set the font:
<TextBlock>
<Run Text="Variable Name: " FontFamily="{Binding FontName}"/>
<Run Text="{Binding Name}"/>
</TextBlock>
If the text in the TextBlock is wrapped using TextWrapping="Wrap" the runs will wrap around as expected. This does not apply to the question but can make using Run elements superior to stacking TextBlock elements in a StackPanel.
Extract out seperate TextBlock and set FontFamily on that TextBlock. Wrap both TextBlocks in StackPanel and set the orientation to Horizontal -
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Variable Name: " FontFamily="Comic Sans MS"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
<TextBlock Text="{Binding Value,StringFormat='Value: {0}'}"/>
</StackPanel>
You could do something like:
<StackPanel Orientation=Horizontal>
<TextBlock Text="Variable Name: "/>
<TextBlock Text={Binding Name} FontWeight="Bold"/>
</StackPanel>
I have a TextBlock with a tooltip that displays the same data, in case of truncation. However if the property that TextBlock.Text and the tooltip's text are bound to is empty (null or zero length string) the tooltip appears as a small empty box. Is there a way to hide this and show no tooltip in this case?
<TextBlock Text="{Binding Text}">
<util:ToolTipManager.ToolTip>
<TextBlock TextWrapping="Wrap" Text="{Binding Text}" />
</util:ToolTipManager.ToolTip>
</TextBlock>
I have tried using a StringToVisibilityConverter by adding Visibility="{Binding Text, Converter={StaticResource StringToVisConverter}}" to the TextBlock without any luck.
I also tried implementing the answer given Hide tooltip if binding is null but that seems specific to their set-up (or at least I haven't figured out how to adapt it successfully).
(ToolTipManager is from http://www.codeproject.com/Articles/36078/Silverlight-2-0-How-to-use-a-DataBinding-with-the, used to provide the data binding for the tooltip.)
Edit:
In response to the comments, here is the XAML I tried for the related question mentioned above:
<TextBlock Text="{Binding PointName}">
<local:ToolTipManager.ToolTip>
<Grid>
<TextBlock TextWrapping="Wrap" Text="{Binding PointName}"/>
<Rectangle Fill="Transparent" Visibility="{Binding PointName, Converter={StaticResource StringToVisConverter}}" />
</Grid>
</local:ToolTipManager.ToolTip>
</TextBlock>
And here is my String to Visibility converter code:
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
string visible = (string)value;
return (!String.IsNullOrWhiteSpace(visible) ? Visibility.Visible : Visibility.Collapsed);
}
I assume you are using Siverlight 4 as it is one of your tags.
In Silverlight 4, I am pretty sure that you don't need the ToolTipManager anymore.
You can just wrap the Rectangle and the TextBlock with a Grid, like this,
<Grid>
<TextBlock Text="{Binding PointName}"/>
<Rectangle Fill="Transparent" Visibility="{Binding PointName, Converter={StaticResource BooleanToVisibilityConverter}}" ToolTipService.ToolTip="{Binding PointName}"/>
</Grid>
UPDATE:
<Grid>
<TextBlock Text="{Binding PointName}"/>
<Rectangle Fill="Transparent" Visibility="{Binding PointName, Converter={StaticResource BooleanToVisibilityConverter}}">
<ToolTipService.ToolTip>
<TextBlock TextWrapping="Wrap" Text="{Binding PointName}"/>
</ToolTipService.ToolTip>
</Rectangle>
</Grid>
If you are using Silverlight 5, the following seems to work:
<ToolTipService.ToolTip>
<ToolTip Visibility="{Binding WhatDeterminesTooltipVisibility}">
<Border Background="Azure" Width="100" />
</ToolTip>
</ToolTipService.ToolTip>
In a WPF application I load news from an RSS feed. The contents are displayed in a TextBlock. This TextBlock has a certain size. Contents are cut off by the TextTrimming method.
Now I would like at the end of each TextBlock to insert a hyperlink button. The only problem is I do not know exactly what position will be cut on my string. Is there a way to figure this out?
When I insert my Text in my TextBlock and then my Hyperlink-Button, my HyperlinkButton will be cut of. Can I prevent to cut off my HyperlinkButton?
XAML-Code:
<TextBlock Name="myText" />
C#-Code:
Hyperlink hlink = new Hyperlink(new Run("here"));
myText.Inlines.Clear();
myText.Inlines.Add(value); //description from RSS Feed
myText.Inlines.Add(hlink);
Why not just add the HyperLink after the text, by replacing both items in a StackPanel?
If I understood your requirements this is one way to achieve your goals:
<StackPanel>
<DockPanel Width="200">
<TextBlock DockPanel.Dock="Left" Text="A short description." TextTrimming="CharacterEllipsis"/>
<TextBlock DockPanel.Dock="Right" TextAlignment="Right">
<Hyperlink NavigateUri="http://www.google.com">here</Hyperlink>
</TextBlock>
</DockPanel>
<DockPanel Width="200">
<TextBlock DockPanel.Dock="Left" TextTrimming="CharacterEllipsis" MaxWidth="170" Text="A really long descripion of the item." />
<TextBlock DockPanel.Dock="Right" TextAlignment="Right">
<Hyperlink NavigateUri="http://www.google.com">here</Hyperlink>
</TextBlock>
</DockPanel>
</StackPanel>
So the DockPanel control might be a good candidate to consider.
Slightly more convenient is to use a :
<TextBlock>
<Run Text="Short description"/>
<Hyperlink NavigateUri="http://www.google.com">here</Hyperlink>
</TextBlock>
I have a textblock which is inside a listbox and I am trying to write an if statement which is dependant on the contents of this textblock. I am trying to get the data from the TextBlack which I have named "category1" however when I try to write my if statement I am getting a message which just says
"the name category1 does not exist in the current context"
I tired moving that TextBLock out of the ListBox and it works fine but wont work while its inside there. Does anyone know how to reference this textblock.
Here is the my XAML code
<ListBox x:Name="HINList" Margin="0,300,-12,0" ItemsSource="{Binding Details}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding HINNumber}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding CategoryLetter}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="category1" Text="{Binding Category1}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="{Binding Category2}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="{Binding Category3}" TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Assuming you're writing your if statement in the code behind file, wouldn't something like:
if(((WhateverTypeIsInDetailsCollection)HINList.SelectedItem).Category1 == something) {
// then do whatever you want
}
As Russell pointed out there is a category1 item for every entry in the list. I assume you wanted to do something with the selected item.
This is due to xaml namescopes. The names inside a DataTemplate are in a different namescope than outside, that's why you can't access them (what #Russell pointed is part of why it's done this way).
I think that you want to access that field for the "Category1" property on the selected item of the HINList ListBox that is bound to the Details collection. What you can do is set the binding on the Category1 to be two way, and bind the SelectedItem of the ListBox to a Detail item like so:
xaml:
<ListBox x:Name="HINList" ItemsSource="{Binding Details}"
SelectedItem={Binding SelectedDetailItem, Mode=TwoWay}>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432">
<TextBlock Text="{Binding Category1, Mode=TwoWay}" TextWrapping="Wrap" .../>
<!-- the other fields -->
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
code-behind
if(SelectedDetailsItem.Category1==...)
{
....
}
Hope this helps :)