Silverlight datagrid cell multiline - c#

Is it possible in a Silverlight Datagrid to manually define where the line break should be? (instead of automatically wrapping to the next line when the border is reached)
This seems like to be the code (source):
<sdk:DataGridTextColumn
Header="Address"
Width="150"
Binding="{Binding Address}" >
<sdk:DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</sdk:DataGridTextColumn.ElementStyle>
</sdk:DataGridTextColumn>
But how do i manually make the line break?

It is possible in common WPF controls so I believe it should be possible on Silverlight as well. Basically what you need is to target the TextBlock control on each cell of the column, similarly to what is being done to give it a text wrapping style.
As you don't clarify from your question wheter you want to assign the text programmatically or on the XAML, I am going to give you a hint on how to do both.
You can assign the text programmatically using an approach similar to this answer:
txtBlock.Inlines.Add("This is the first paragraph");
txtBlock.Inlines.Add(new LineBreak());
txtBlock.Inlines.Add("This is the second paragraph");
On the other hand, if you want to assign the text directly on XAML, you can use the <LineBreak/> tag directly inside your text, as mentioned in this answer:
<TextBlock>
This is the first paragraph <LineBreak/>
This is the second paragraph
</TextBlock>

Related

Can't set Foreground color in DataGrid using Binding

I'm working with a DataGrid in a Windows UWP application.
I'm trying to set the Foreground property of a DataGridTextColumn by binding it to a color value in my model. My model object has a property, called Color, that returns a value of type Windows.UI.Xaml.Media.Brush. As this is the same type as the Foreground property, I assumed I could set it directly, like this:
<DataGridTextColumn Foreground="{Binding Path=Color}" ...
However, this results in a runtime exception that says, "Failed to assign property".
I have seen code samples that appear to be doing the same thing, and I'm struggling to understand why this won't work.
Referring to the document, we know that a property must be a dependency property to be the target of a {Binding} markup extension, but {x:Bind} does not have this requirement as it uses generated code to apply its binding values. From the code of Foreground of DataGridTextColumn, the Foreground property is not a dependency property, therefore it is not supported to do the data binding by {Binding} extension for the Foreground property.
You could custom a CellTemplate to set a data binding for the Foreground property for a DataGridTemplateColumn instance.
For example:
<controls:DataGrid.Columns>
<controls:DataGridTemplateColumn Header="header">
<controls:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate x:DataType="local:Customer">
<StackPanel >
//MyBrush is a SolidColorBrush in Customer class, adjust it for your scenario
<TextBlock Text="{x:Bind FirstName}" Foreground="{x:Bind MyBrush}"/>
</StackPanel>
</DataTemplate>
</controls:DataGridTemplateColumn.CellEditingTemplate>
</controls:DataGridTemplateColumn>
Unfortunately, this issue is still vexing me.
I thought I had managed to set the row color dynamically, but it turns out that the dynamic color I chose was the same as the default color, and when I changed it, nothing happened.
So I'm still looking for a solution.
I have a lot of columns. It would not be feasible for me to implement a solution that required pasting 10+ lines of XML dozens of times.
Isn't there some way to do this in code? Can I just grab the UI element containing the text somehow, and modify it?
Here is an example of what I am doing. The TextWrapping and TextAlignment settings work, but the Foreground setting doesn't work, even if I assign it a constant value.
<controls:DataGridTextColumn x:Name="notesCol" Binding="{Binding Notes, Mode=OneWay}" MaxWidth="500" Header="Notes" Tag="Notes">
<controls:DataGridTextColumn.ElementStyle>
<Style TargetType="TextBlock">
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
<Setter Property="TextBlock.TextAlignment" Value="Left"/>
<Setter Property="TextBlock.Foreground" Value="Green"/>
</Style>
</controls:DataGridTextColumn.ElementStyle>
</controls:DataGridTextColumn>

Font Size WPF program source

I have a problem with WPF. I need WPF only for changing font size. So, I want to make something like text editor but only with changing the Font Size. I need to have text box/ text block and a button ("Font Size") which when you click it opens a new textbox and you add the desire size of the text. After you add the number it binds it and applies it to the text.
I can not write the code and will be very grateful if someone helps me! Thanks in advance!
You can use the following :
Style TargetType="{x:Type Window}">
<Setter Property="FontSize" Value="15" />
/Style>
and then add the dynamic change :
Say, textbox1 is the textbox where you want to add size value..
TextBlock FontFamily="Arial" Text="Sample text" FontSize="{Binding TextSize}" />
or
Application.Current.MainWindow.FontSize = Textbox1.text.toInt32();

GroupLevelIndicatorPane causes ColumnStretchMode=ALL to not fit columns

I have an Xceed datagrid that uses ColumnStretchMode=ALL to make the columns fit in the grid.
It has been working perfectly, until I added a GroupLevelIndicatorPane. Once I added that, the grid no longer fits right (it is off by the width of the GroupLevelIndicatorWidth amount).
I have been looking for a way to cause this calculation to take that pane into account with out any luck.
Has anyone else ever seen this with the Xceed controls? (I don't have current Xceed support so they will not help me.)
UPDATE:
I found out why this was happening. I had something to this effect in my grid setup:
<Style TargetType="{x:Type xcdg:GroupLevelIndicatorPane}">
<Setter Property="Visibility" Value="{Binding RelativeSource=
{RelativeSource FindAncestor, AncestorType={x:Type xcdg:DataRow}},
Path=DataContext.ShouldIndent, Converter=
{StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}" />
</Style>
I caused the GroupLevelIndicatorPane to be collapsed for some types of groups. I took it out and the calculations started working right again.
Guess I need to find another way to have some groups not indent.
Turns out I had to apply the visibility on the actual GroupLevelIndicatorPane (not on the style). Once I did that the ColumnStretchMode=ALL calculated correctly.
Not sure why it matters, but it does.

Get object value from Listbox Item

Im currently developing an Windows Phone 7.0 Application with C#. I got an Listbox whichs items is based on the results of an WCF-Service. I've created my own object which contains a few values that have been fetched from an database. The problem is that i don't know how to change the content of each Listbox Item depending on the values of that items parameters that was fetched using the webservice.
Structure:
User enters the XAML Page
An connection is being opened between the client and the webservice
The webservice returns an List<Friend> The important parameter inside Friend is called Verified
The listbox items is set using: lstFriends.ItemsSource = e.Result;
What i want to do:
I want to check in each Listbox Item after the parameter Verified and check it's value.
Depending on if the parameter is true or false a TextBlock inside the Listbox Item should have different text.
Thanks
This is probably an ugly way to do it with no code-behind, but what you could do is create a template for your listboxitem that includes two textblocks (something) like this:
<Style x:Key="ListBoxItemStyle1" TargetType="ListBoxItem">
<Setter Properties... />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<TextBlock Text="Verified" Visibility={Binding Verified, Converter="{StaticResource BoolToVisibilityConverter}" />
<TextBlock Text="Not Verified" Visibility={Binding Verified, Converter="{StaticResource ReverseBoolToVisibilityConverter}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
You would then have to write two converters: BoolToVisibilityConverter to change the boolean value of Verified to Visible if True and Collapsed if False for the first text block and ReverseBoolToVisibilityConverter to change the boolean value of Verified to Visible if False and Collapsed if True on the second text block. This way one textblock will always be visible in the listboxitem and one will always be collapsed, depending on the value of the Verified property.
If you don't know how to do value converters, you can look HERE.
This isn't tested and is not all of the code you'd need, but it should work. This assumes that the two different text blocks will always contain the same text and that the Verified property is a boolean property, if not then you might want to figure out another way to do it.
On second thought, you could just do ONE value converter and one textblock and convert the value of Verified to the text you want. That would be easier.
<TextBlock Text="{Binding Verified, Converter="{StaticResource VerifiedToTextConverter}" />

Focus-dependent text change for TextBoxes in WPF

I'm writing an application in WPF using the MVVM-pattern and will really often use TextBoxes.
I don't want to use labels for the user to know user what the text box is for, i.e. I don't want something like this:
<TextBlock> Name: </TextBlock>
<TextBox />
Instead, I would like the TextBox to contain its own label. Statically, you would express it like this:
<TextBox>Name</TextBox>
If the cursor is displayed in the textbox, i.e. the TextBox gains focus, I want the description text to disappear. If the TextBox is left empty and it loses the focus, the description text should be shown again. It's similar to the search textbox of StackOverflow or the one of Firefox. (please tell me if your not sure what I mean).
One TextBox's label may change at runtime, dependending on e.g. a ComboBox's selected element or a value in my ViewModel. (It's like in Firefox's search TextBox, if you select google from the search engins' menu, the TextBox's label changes to "Google", if you select "Yahoo" its set to "Yahoo"). Thus I want to be able to bind the label's content.
Consider that I may already have a Binding on the Text-Property of the TextBox.
How can implement such a behaviour and make it reusable for any of my TextBox's? Code is welcome but not needed; a description of what to do is enough.
Thank you in advance.
Here is a style I think is exactly what you are looking for, and it's pure XAML.
<Style x:Key="WatermarkTextBox" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Grid>
<Border x:Name="BorderBase" Background="White" BorderThickness="1.4,1.4,1,1" BorderBrush="Silver">
<Label x:Name="TextPrompt"
Content="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Tag}"
Background="{TemplateBinding Background}" Visibility="Collapsed"
Focusable="False" Foreground="Silver"/>
</Border>
<ScrollViewer Margin="0" x:Name="PART_ContentHost" Foreground="Black"/>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsFocused" Value="False"/>
<Condition Property="Text" Value=""/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" TargetName="TextPrompt" Value="Visible"/>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" TargetName="BorderBase" Value="Black"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DimGray" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usage is:
<TextBox Style="{StaticResource WatermarkTextBox}" Tag="Full Name"/>
where Tag is the help message you want to show.
You could clean up this style for your own use, but the most important part is the which controls hiding/showing the helper text.
It's worth noting as well, there is already a DependencyObject available for storing the helper text, so you don't need to create your own with this method.
FrameworkElement.Tag is available for holding arbitrary information about this element. That's why we set the Tag property:
http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.tag.aspx
You could derive from TextBox and implement your behaviour. The TextBox offers the events GotFocus/LostFocus (or the methods OnGotFocus/OnLostFocus respectively) which should help. You also should consider offering a new DepedencyProperty, so you can define the default text in xaml and bind it to other controls/resources etc.
To amplify on my suggestion about using an adorner.
An Adorner is basically an element, rendered on its own layer, that appears over/around another element. For instance, if you implement validation in a binding, the red box that decorates an invalid control is an adorner - it's not part of the control, and it can be (and is) applied to all kinds of controls. See the Adorners section of the WPF docs for a simple but clear example.
I thought of an Adorner for a couple of reasons. The principal one is that the behavior you're describing might not necessarily be confined to a TextBox. You might, for instance, want to have a ComboBox exhibit the same behavior. Implementing an Adorner would give you a consistent way to implement this functionality across multiple controls (though it doesn't make sense in, say, a CheckBox or a ProgressBar). A second is that you wouldn't have to do anything to the underlying control more elaborate than implementing triggers to display and hide the Adorner in response to focus events. Adorners are a bit of a pain in the butt to implement, but it's worth knowing how to.
All that said, I like mattjf's answer a lot more than I like mine. The only disadvantages I see with that approach are 1) It only works with the TextBox; you need to implemnent a new version of the style every time you want to use the approach on another control, 2) I may just be engaging in magical thinking, but every time I ever used the Tag property in WinForms it told me (once I learned to listen) that I was building something fragile. I don't know for sure that this is also true in WPF, but I bet it is.
My comment on using the bound Text property probably needs amplification. If you use the Text property to store the field label, then you've got a number of hard-to-solve problems. First, since it's a bound property, changing its value in the TextBox will change it in the source. So now your source needs to know a lot of information about the state of the UI - does the control currently have the focus? If the value of the Text property is Foo, does that mean that the label is Foo, or the user typed in Foo? There are probably ways that you can manage this, but the best way to manage it is to not have to.
(One other problem with this paradigm: What should be the behavior be if the user wants the value of the TextBox to be the empty string?)

Categories