newbie question, please forgive...
I'm developing a Wpf UserControl that will eventually be bound to a business object. The usercontrol is little more than a series of laid out TextBlocks, and perhaps (later) an image or two.
As I'm laying out the usercontrol, I can put dummy text into all the TextBlocks so I can see what the usercontrol will look like, but as soon as I change the text property to contain the Binding information:
<TextBlock Margin="0,12.8,42,0" Name="lblLastName"
FontSize="8" Height="19"
VerticalAlignment="Top"
Text="{Binding Mode=OneWay, Path=LastName}"/>
Then I can no longer see the textbox, or any "placeholder" text. This makes it very difficult to adjust the location and sizes of all the controls on the UserControl. In WinFormas programming, you could set binding information independently of the Text property, so you could at least see the Placeholder text during design time development. It's going to be pretty hard to visually arrange a bunch of invisible TextBlocks! What's the standard solution for this?
You can change the Background of the TextBlock to something visible enough if it's the same color as the visuals behind it, and set HorizontalAlignment to "Stretch". This way it will fill the available width. That, or set the MinWidth to an explicit number. No text, but it will be visible.
I have successfully used design time mock objects to get a good preview of what everything will look like:
Viewing Design Time Data in Visual Studio 2008 Cider Designer in WPF and Silverlight Projects
Related
I have a string of text that I need to display. I currently display it in a textbox.
My requirements have changed and now I need to display parts of this string in Red.
I have looked and all I can see for displaying text in several colors is a WebBrowser or RichTextbox. Both of these are more complex then I was hoping to use.
I can format the text string in any way (using any kind of markup).
Is there some kind of simple markup control out there for wpf? (Note: This will be going on a datagrid that can have many hundreds of rows, so it cannot be a memory/processing intensive control.)
You can use a TextBlock if it doesn't need to be edited.
From above link:
TextBlock is designed to be lightweight, and is geared specifically at integrating small portions of flow content into a user interface (UI). TextBlock is optimized for single-line display, and provides good performance for displaying up to a few lines of content.
TextBlock is not optimized for scenarios that need to display more than a few lines of content; for such scenarios, a FlowDocument coupled with an appropriate viewing control is a better choice than TextBlock, in terms of performance. After TextBlock, FlowDocumentScrollViewer is the next lightest-weight control for displaying flow content, and simply provides a scrolling content area with minimal UI. FlowDocumentPageViewer is optimized around "page-at-a-time" viewing mode for flow content. Finally, FlowDocumentReader supports the richest set functionality for viewing flow content, but is correspondingly heavier-weight.
Modified example from link showing Red Text:
<Grid>
<TextBlock TextWrapping="Wrap" >
<Bold>TextBlock</Bold> is designed to be <Italic>lightweight</Italic>
and is geared <Run Foreground="Red">specifically</Run> at integrating
<Italic>small</Italic> portions of flow content into a UI.
</TextBlock>
</Grid>
AvalonEdit should do what you want. There is a Nuget package for it. See here also:
http://www.codeproject.com/Articles/42490/Using-AvalonEdit-WPF-Text-Editor
Also, if the text is not being edited, I think you should probably use something like a ListBox with custom item templates -- especially if the entire line is to be highlighted.
I need to create a TreeView type controller that will display rich text.
Example:
» Signed by Person Name
» Certified by Person Name
Content of the TreeViewItem is easy as I can simply put TextBlock inside, but header don't allow for multiple font style declarations.
I'm really a beginner in XAML and I work in ExpressionBlend (although I don't shy away from coding). I would really appreciate if someone push me into right direction.
You can put a "Run" in a TextBlock to change the font.
e.g.
<TextBlock>Hello<Run FontStyle="Bold">World</Run></TextBlock>
You can set the content of the header to anything you want
<TreeViewItem>
<TreeViewItem.Header>
<TextBlock>Hello<Run FontStyle="Bold">World</Run></TextBlock>
</TreeViewItem.Header>
</TreeViewItem>
When you do this:
<TreeViewItem>Hello</TreeViewItem>
You are not telling the XAML parser what property you want to put 'Hello' into. The XAML parser will look at the type (TreeViewItem) and see which is set as the 'ContentProperty', in this case it's the property called 'Header'. Because you have not specified what 'Hello' is, it assumes a string. Since a string can't actually be displayed as content in WPF, it has to create a control to display the string. The ValueConverter for TreeViewItem is set up to provide a TextBlock control and set the Text of this control to the string you entered. So what's happening behind the scenes is a lot more than you can see :)
All of this stuff you can do with your own controls
You should probably read up on WPF templating, content controls, content presenter, styles etc. There are a lot of powerful things you can do with WPF - for instance, make every single button in your application have the same layout and style and add an image to the front of the button without any code (just with a few lines of XAML)
Have a look here for a beginners guide to templating
http://msdn.microsoft.com/en-us/magazine/cc163497.aspx
I am making some things in silverligth with marked up text in XAML.
Everything is going fine until i came up with this.
I am trying to give my text a background color but it says the property does not exist.
the property for a foreground does exist.
is there a way to still give my text parts a background color?
image in link:
http://img146.imageshack.us/img146/537/highligths.png
This is one of those annoying Silverlight vs. WPF differences. Neither TextBlock nor Run elements provide a Background property in Silverlight. You need to wrap them in a Border:
<Border Background="Red">
<TextBlock>Test please ignore</TextBlock>
</Border>
Thus it's annoyingly involved to do precisely what you want, but possible. If the text you want to display is not well known ahead of time, your best bet is to look at a third party RichTextBox control such as Telerik's RadRichTextBox.
Please tell me you did that with Textblock and Runs. I think the Run element can support foreground and background properties. I know you can twist the content to support both you just have to be clever about the controls inside the Textblock.
(I am trying to learn WPF using tutorials and documentation, and trying to develop a user interface for my backend-complete application while I do say. I've heard people say that the learning curve is quite steep. But sometimes I wonder whether what I'm trying to do is actually something that's hard to do in WPF, or if it's simple but I'm thinking in wrong terms, or if it's neither, it's quite simple but I just happen not to know how.)
Here's my current question. I wanted clicking that clicking some part of my UI will bring up a 'popup' where the user can enter more information. I would like a 'lightbox-style' popup, i.e. the popup is modal to the page, it darkens the rest of the page to become the center of attention, etc. These are seen commonly on Web sites.
A bit of searching led me to the WPF Popup control. I added it, put my content in, set the IsOpen property to True, and -- presto! A popup. Then I added an invisible Rectangle that covers my whole window, and set it to Visible as well when I want my popup to open. Great!
So now I wanted to do this dynamically, because sometimes I will be loading a record which will sometimes have a need to open another control (a UserControl) in a popup to edit its information. So I made myself a method called OpenPopup. But I can't seem to find a way to write this method using WPF. In Windows Forms I'd have written: (I use VB.NET)
Sub ShowPopup (form as Form, ctrl as Control)
'Create 'rect' as new dark rectangle control
'Z-order it to the top
'form.Controls.Add 'rect'
'form.Controls.Add ctrl
'Z-order 'ctrl' to the top
'Center 'ctrl'
'Set focus to it
End Sub
But with WPF I run into problems:
1) I can't add it to the WPF window, because it already has a child.
2) If that child is a Canvas, that's not too bad. I can detect that, and add it to the Canvas. I have to find some way to set its Left, Top etc. properties and Width and Height, since those do not seem to be properties of the Rectangle control but rather extended by the Canvas object -- in XAML they're called Cavnas.Top etc. but Intellisense is not showing them when I try to use it in code.
3) But if it's a StackPanel? Then my rectangle will just be stacked below the other controls! And not covering them! Is there a way around this?
4) And if the window contains only one control and no container control at all?
5) I think there were more problems I ran into. But let's start with these.
Thanks in advance for your help.
1) I can't add it to the WPF window, because it already has a child.
Ah, the evils of codebehind. The solution is not to add it to the visual tree, it is to place it in the visual tree, ready and waiting to pounce, but hide it from the user's view.
Here's a sample you can drop in Kaxaml that demonstrates the point. Set the Lightbox Grid's Visibility to Hidden to access the hidden content.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Viewbox>
<TextBox Text="SIMULATING CONTENT" />
</Viewbox>
<Grid x:Name="Lightbox" Visibility="Visible">
<Rectangle Fill="Black" Opacity=".5"/>
<Border
Margin="100"
Background="white"
BorderBrush="CornflowerBlue"
BorderThickness="4"
CornerRadius="20">
<Viewbox Margin="25">
<TextBox Text="SIMULATING LIGHTBOX"/>
</Viewbox>
</Border>
</Grid>
</Grid>
</Page>
2) (snip) Intellisense is not showing them when I try to use it in code.
Canvas.Top etal are Attached Properties. Attached Properties are extremely convenient and easy to use in XAML, but they are very confusing and hard to use from code. Another reason why codebehind is evil.
3) But if it's a StackPanel? Then my rectangle will just be stacked below the other controls! And not covering them! Is there a way around this?
I redirect you back to 1. There are also many other container controls in WPF. You should investigate them and observe how they control layout. For instance, my use of the Grid was not to make use of its ability to block off sections of UI for controls, but for its ability to layer controls ontop of each other and to stretch them out to their maximum available size for the available space (the viewboxes are just there to zoom the controls instead of stretch them).
4) And if the window contains only one control and no container control at all?
The root of a window would almost always be a container control. But you control that, so if you needed to add controls to the visual tree at runtime you could easily ensure the child of the window is a container control you could deal with.
5) I think there were more problems I ran into. But let's start with these.
No kidding. My number one suggestion for people in your situation is to drop what you're doing and learn about MVVM. The Model-View-ViewModel is a very simple way to code WPF applications that takes advantage of many of the features of WPF--databinding, templating, commands, etc. It allows you to code your logic not in codebehind (RETCH) but in easy to create and test classes.
FindAncestor RelativeSource only supports 'Self' and 'TemplatedParent',
but I have to bind the width of a popup to the width of the page.
Giving the page a name causes problems because sometimes it will
throw exceptions saying a control with that name is already present in the visual tree.
<Popup IsOpen="True"
Width="{Binding ElementName=BordPage, Path=Width}"
Height="{Binding ElementName=BordPage, Path=Height}">
Background information:
I'm using a SL4 navigation based application here. BordPage is a navigation page,
which I'm using multiple times within the application. So giving it a name in the page itself is not really a good idea,
but I don't know how else I can bind to the width and height of the page.
What I'm trying to do is have a black border (with opacity 0.8) cover the entire screen,
(including the controls of the MainPage). Then on top of that I want to display some other controls.
Since the application is touch controlled, providing the user with a ComboBox to select a value doesn't really work wel. Instead I want to show this black overlay window with a listbox taking up most of the screen so the user can simply touch the value he wants with a single click.
Update: I just realized I can use the ChildWindow class to do this.
But my original question remains.
My general solution for this problem is by writing a custom behavior. It's not a pure XAML solution but it gives you a lot more flexibility.
Create a behavior that searches up the VisualTree to find the right item and then have it set the width of the Popup correctly.
It may be a little more complicated than a straight binding but it avoids all the naming issues.
Put the following in the constructor of your control so you can avoid naming it:
DataContext = this;