WPF TreeView: WordWrap - wpf

I have this project that displays hierarchical data with huge amounts of text, and I'm transitioning from winforms to wpf, and with winforms treeview not wordwrapping out of the box I really wanna know how to do this in wpf. Is it possible to have Items in the TreeView use word wrapping, out of the box?
I've looped through a fair amount of threads and google results, but none got me any working method. ScrollViewer.HorizontalScrollBarVisibility="false" got me nowhere either.
If its not there, how would one approach the implementation? I'm quite new to wpf, so I'd appreciate a direction to push in.
Oh, and the framework is 3.5.

I think you'd have to bind the width of the root control of the treeview's node template to the actual width of the treeview itself. So something like the following:
<TreeView x:Name="tv">
<TreeView.ItemTemplate>
<DataTemplate TargetType={x:Type TreeViewItem}">
<TextBlock Text="{Binding PropertyToBind}" Width="{Binding ActualWidth, ElementName=tv}" TextWrapping="Wrap"/>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
You should also be able to set the width binding using a relative source, but I can't recall the syntax.
Usually these types of problems are solved by forcibly constraining the element inside of its parent element (even though it should technically already do that). Just an idea. Good luck.

Related

Create/Modify new WPF UI components

I want to change the graphical UI elements in WPF.
For example, I want to use a kind of a stack panel, but on the other hand I want to show my details in a star, or circle, etc.
Maybe setting a bitmap as a background, but I am working with lots of Data using zoom tool.
I found tutorials, documentation only for changing attributes of "old components", but nothing to make new ones.
Great resource for WPF beginners is www.wpftutorial.net
One of the best idea of WPF is separation of concerns:
UI Control = Logic in Code/XAML + Template
Using templates in XAML we can vary representation without modifying the control.
For example, if there is a need in creation of list of items. Then we can use ListBox control:
<ListBox>
<ListBoxItem>USA</ListBoxItem>
<ListBoxItem>UK</ListBoxItem>
</ListBox>
By default LisboxItem internal part is just binded TextBlock.
Now making UI modification without changing control source code:
<ListBox ImageSource="{Binding PathToSource}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{StaticResource ProjectIcon}"/>
<TextBlock Text="{Binding Path=PropertyName}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
there appears image and text.
If there is a need in creating exclusive control then you can always use Custom Control.
Using raster images (e.g. PNG) is not good point, especially with zoom behaviour. If it is possible better to use vector images, that can be created in XAML or imported from SVG.

WPF TabControl and DataGrid bugs, bugs and bugs

for everyone, I found different problems with WPF, the TabControl and the DataGrid. Especially if the TabControl ItemsSource is bound.
Problems i found:
Selection in DataGrid is not visible after switch Tabs back and forth
DataGrid looses sorting on tab switch (SortDescriptions of CollectionView.GetDefaultCollection is cleared on unload)
if a DataGrid cell has focus (is in edit mode) and you click on another tab, two things can happen: 1.) the bound object will not be updated; 2.) if the object is invalid you receive an error DeferRefresh not allowed during edit, or something like this
DataGridComboBox and possibly other controls do clear their values if you switch to another tab if you are working with bound TabControls and DataTemplates. This clears any selection.
So now my question: Is there any ThirdParty controls which perform better in this scenarios?
You also can vote here http://connect.microsoft.com/VisualStudio/feedback/details/807849/databound-tabcontrol-bugs
I got answer from Microsoft it won't fix because not enough people have this problems.
I know some fixes, but they are some really not clean (f.e. using reflection). Maybe you have some ideas?
Hmmm, interesting post though I bet there are all not bugs. I think Microsoft hasnt even taken a look at those things. They might never do. I would appreciate it much if you could post or upload code of all those issues you might be thinking they are all buggy bugs.
Btw, what do you mean with TabControl ItemsSource is bound?
Here is my feedback on this from the info you gave us in the question. 1) You select something, you click away anywhere, no matter if tabitem or another window, you will lose focus, the selection will turn inactive means to slightly grey color. 2) Unloading means removing a control from VisualTree and so CollectionView must be cleared to release memory. This is good so since you dont want memory leaks. 3) If the cell's edit template contains controls which shall update the binding's source on focus lost then for sure that will happen. If you happen to be using a template for TabItems then the template will be mostly reused (means with same instance) and so you might end up taking the seat away from DataGrid' ass which is futhermore not a bug but rather something you wouldnt like to happen to you either. Therefore the DataGrid might be yelling "yo, no fooling around while I am editing a cell". 4) Same as in #3 it depends what you doing and how you define the templates. Consided mostly if template is in resources with a key then the template will be reused.
Just post us code please and let us take a look. I bet you might be doing something very "wpf-unlikely". :)
If those things really happen to be "buggies" (others review the same behavior), I bet there are workarounds for them. :)
Personally I have a feeling that all those things happen because you are using data bound TabControl. Whatever that might mean. I am excited to see what are data bound TabControls and how are they bound? How do you define those templates.
I have the same issue.
Fix to DataGridComboBox issue may be to specify the ItemsSource of the ComboBox as the DataContext property of the TabControl instead of the DataGrid as the DataGrid is removed from the visual tree when you select another tab:
<TabControl x:Name="tabControl" Behaviours:TabContent.IsCached="True">
<TabItem Header="Tab1" Content="{Binding}" ContentTemplate="{StaticResource Tab1}"/>
<TabItem Header="Tab2" Content="{Binding}" ContentTemplate="{StaticResource Tab2}"/>
</TabControl>
<DataTemplate x:Key="Tab1">
<DataGrid ItemsSource="{Binding Entities}" x:Name="dataGrid">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="100"/>
<DataGridTemplateColumn Header="Position" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Position}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox SelectedItem="{Binding Position, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Path=DataContext.Positions, ElementName=tabControl}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>

WPF TreeView question

Is it possible to store some data in every item of a TreeView control? I mean, something useful (e.g. a string) besides the header text?
Thanks.
Yes, WPF is "lookless", so your actual data can be anything you want it to be, and a TreeView is just a Template used to display the data to the user in a pre-determined way.
You can overwrite any part of that Template to be whatever you want, and/or have it bind to your data however you want.
Edit
I'm no expert on using the TreeView, but if you had a DataContext of List<Folder>, and each Folder object had a Name and a FullPath property, your TreeView could look something like this:
<TreeView ItemsSource="{Binding MyFolderList}">
<TreeView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"
ToolTip="{Binding FullPath}" />
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
If you haven't already, I'd highly recommend looking into the MVVM design pattern when working with WPF. Basically your application is your classes (ViewModels), and the Controls/XAML (Views) are just a pretty layer that sits on top of your classes to make them user-friendly.
This is an important concept when switching from a WinForms TreeView to a WPF TreeView
It depends on what you mean by store data...
If you're just talking UI customization Rachel's answer above works.
If you're talking about storing arbitrary object values, such as information about the TreeViewItem, or maybe a relation between two items, you can use the Tag property of TreeViewItem. For example, I had to write a mapping UI where two trees linked together where each TreeViewItem from the first tree, could connect to 1 TreeViewItems of the second tree. I used the Tag property of the first TreeViewItem to store the connecting TreeViewItem.

Setting the background color of separate WPF ListBox items

I want to set the background color separately for each item in a WPF ListBox. e.g. If I am adding Widgets to the ListBox, I might set the background color for each one based on the type of widget. This must be done in code (not XAML) as I only know what the items are at run time.
I know how to use ItemContainerStyle to set the style for all items, but how do you do it separately for each item?
Yes you do set ItemContainerStyle, using a StyleSelector.
This example at MSDN is exactly what you are looking for.
There are lots of ways to do this.
One is to use a StyleSelector, as loxxy suggests. This is pretty low on my list, because that kind of code is harder to read (well, find) and test than I'd like.
Another is to use a DataTrigger in the style. This is simple, if (and only if) the items all implement a common property that can be used in the trigger. You might be well served by implementing a wrapper class that exposes this common property, and contains the logic that figures out what value to assign to the property based on the object it's wrapping. (Whether or not this is easier than a StyleSelector is certainly arguable.)
If the items are really and truly heterogeneous, you can accomplish the result by using data templates, e.g.:
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:Foo}">
<TextBlock Text="{Binding FooText}" Background="Red"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Bar}">
<TextBlock Text="{Binding BarText}" Background="Yellow"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Baz}">
<TextBlock Text="{Binding BazText}" Background="PapayaWhip"/>
</DataTemplate>
</ListBox.Resources>
etc. This would generally be my first choice, but your question doesn't really explain enough about the circumstances to know if it's the right way to go or not.

WPF Creating a ControlTemplate that is DataBound

I have a control bound to an Object and all is well but I want to turn it into a control template bound to different objects of a similar type. I would like to do this exclusively in xaml, if possible. Any good tutorials that outline the steps?
<TextBlock Text="{Binding Source={StaticResource BorderControl}, Path=ControlName}"/>
EDIT: With a little more experience, it turns out what I need is the ability to Set the Binding source based on a property of the control. i.e.
<TextBlock Text="{Binding Source={StaticResource {TemplateBinding Tag}}, Path=ControlName}"/>
The control exists within a ControlTemplate but works correctly if I bind it directly to the data -- if that makes a difference. I don't know if this is possible or if it's the correct approach. Any thoughts welcome!
EDIT:
This doesn't work either.
<TextBlock Text="{Binding Source={TemplateBinding Tag}, Path=ControlName}"/>
I think you want ContentPresenter here (http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter.aspx) - think of it as one line of an ItemsControl, it's got a content and a reference to a template that will represent that content.

Resources