Move a popup after databinding - silverlight

I would like to display a popup above my control when the user 'mouse over', problem is that the contents of the popup is a ListBox that databinds so I do not know the size of the control (to set the margins), I have tried every event listed in intellisense on the popup but the ActualHeight of the popup is zero (want to subtract from Margin.Top), any ideas?

For this, I would recommend using a ToolTip. This way you can format the tool tip to show with a list box that is data bound. For example: A normal tooltip would look like:
<sdk:Label Content="{Binding SomeBinding}" Width="Auto" Height="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ToolTipService.ToolTip>
<ToolTip Content="Some tool tip." Name="ttSomeToolTip"></ToolTip>
</ToolTipService.ToolTip>
</sdk:Label>
What I assume you're doing is this:
<sdk:Label Content="{Binding SomeToolTip}" Width="Auto" Height="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ToolTipService.ToolTip>
<ToolTip Name="ttSomeToolTip">
<ListBox ItemsSource="{Binding MyListBoxSource}" SelectedItem="{Binding MySelectedListBoxItem,Mode=TwoWay}">
</ListBox>
</ToolTip>
</ToolTipService.ToolTip>
</sdk:Label>
I can't guarantee that this proposed solution will work, but you have one of two options: Target the LayoutUpdated event for the ToolTip and do a render transform matrix to resize the tool tip container. Theoretically, the tool tip should resize automatically. So if you're not already using the above mentioned approach, try that and see what happens.

You must run code via Dispatcher, then your code runs in UI thread and you have access to control size.
See here

Related

Presenting readonly data in a wpf form

I am searching for the "right" way of styling a textbox for showing read-only data.
Normal if you set a textbox to read-only the text somehow become dimed. What I would like is this
See that the data is read-only
Easily read the text
Be able to copy the text
Should be able to see the control if there is no data.
I could give the background or border another color but maybe I am missing out of something? is there a skilled designer out there (-:
For solve this problem you should use RichTextBox inside TextBlock.
Here is my sample of code read-only TextBlock with scrollbar, auto-wrapping and possibility to copy text >
<DockPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<TextBlock IsEnabled="True" TextWrapping="Wrap" TextAlignment="Justify" HorizontalAlignment="Stretch">
<RichTextBox Background="Transparent" BorderThickness="0" IsDocumentEnabled="True" IsReadOnly="True" />
</TextBlock>
</ScrollViewer>
</DockPanel>

Restoring layout when we use GridSplitter

I am using Gridsplitter control to give the flexibility of resizing the heights of a grid and a tab in a MVVM driven WPF application.
It is working with out any problem, but after I resize the height of any of the controls I navigate to some other screen and comes back to this screen I am losing the changes. The controls are again reset to their default heights.
Can somebody suggest me an efficient way of restoring the changes when we come back ?
This is the code I am using.
<igDP:XamDataGrid Grid.Row="1" Grid.Column="0" DockPanel.Dock="Top" />
<GridSplitter Grid.Row="2" HorizontalAlignment="Stretch"
VerticalAlignment="Center" Height="2"/>
<TabControl Grid.Row="3" Grid.Column="0" DockPanel.Dock="Top">
Thanks in advance.
First it would be nice to see actual code you can do that by pasting some code in your question and the use cyrly brackets under the yellow banner when you start typing ;-).
Secondly It seems like you could use binding with your ViewModel i.e. VM.UserSettings.TabHeight.
and then in .xaml
this is assuming
<Page or Window.DataContext>
<vm:ViewModel />
</Page or Window.DataContext>
<TabControl Height={Binding UserSettings.TabHeight}">
good luck :-)

Get ScrollViewer.ViewPortHeight in XAML

All,
I'm sure this is easy to do, but I'm still trying to do this. I can get the ViewPortHeight of a scrollviewer in code-behind and plug into loaded and size-changed events to manage objects related to ViewPortHeight, but I was wondering if there is a simpler way to do this without going to CodeBehind at all.
i.e. what I would like to do is somehow get ViewPortHeight (and ViewPortWidth) in XAML and Bind them either directly to another element's size property or to my ViewModel (with my own IValueconverter, of course). This way, I hope to more easily manage related controls whenever a window is resized (or whenever a scaletransform is done).
i.e. in PseudoCode, this is what I hope to accomplish (without CodeBehind)
(assuminging MyConverter is an IValueConverter in resources)
<ScrollViewer Name="MyScrollViewer">
<loc:MyControl Width="{Binding Path=ViewPortWidth, ElementName=MyScrollViewer, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource MyConverter}, ConverterParameter=10}" />
</ScrollViewer>
Thanks in advance.
"to manage objects related to ViewportWidth" - that sounds to me like you need a layout container such as Grid which allows you to create rows and columns. Inside those you can place whatever UIElement you wish. You can also tell a cell to have fix size or to use relative values based on avialable space.
If you want to figure out ViewportWidth you will need to do this:
<ScrollViewer Name="MyScrollViewer">
<StackPanel>
<Button Width="100"/>
<Button Width="200"/>
<Button Width="300"/>
<Button Width="400"/>
</StackPanel>
</ScrollViewer>
<TextBlock Text={Binding ElementName=MyScrollViewer, Path=ViewportWidth}"/>
ScollViewer has the property called ViewportWidth. See http://msdn.microsoft.com/en-us/library/system.windows.controls.scrollviewer.aspx
Should be:
<ScrollViewer Name="MyScrollViewer">
<loc:MyControl Width="{Binding Path=ViewportWidth, ElementName=MyScrollViewer, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource MyConverter}, ConverterParameter=10}" />
<!--Notice that it is ViewportWith, not ViewPortWidth-->
</ScrollViewer>

Silverlight 3 Checkbox Listbox bug when scrolling?

I've spent a few minutes searching on Google and have not found anything related to this issue I'm having:
Today I upgraded to the Silverlight 3 SDK and converted a project that I'm working on. I then noticed a bug in my program with a Listbox that has a Checkbox as its DataTemplate.
When one or more items is checked, and I scroll up and down, it seems that a few of the Checkboxes at the extremes get checked off and on randomly. This does not trigger the Checked/Unchecked event, however.
Has anyone seen this behavior? I'm not doing anything out of the ordinary, simply scrolling up and down once at least one checkbox has been checked, and a couple of others that I have not touched seem to get checked on and off repeatedly. This was definitely not happening with the Silverlight 2 SDK.
Here's the XAML definition for my Listbox:
<ListBox x:Name="cBoxSalesmen" Width="135" Height="200"
HorizontalAlignment="Left" VerticalAlignment="Top">
<ListBox.Template>
<ControlTemplate>
<Border Style="{StaticResource BorderStyleThin}">
<StackPanel Orientation="Vertical">
<TextBlock Text="Salesmen" />
<ScrollViewer Height="176" VerticalScrollBarVisibility="Visible" >
<ItemsPresenter />
</ScrollViewer>
</StackPanel>
</Border>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Margin="0" Content="{Binding}" FontSize="10" HorizontalAlignment="Left"
Checked="SalesmenCheckbox_Checked" Unchecked="SalesmenCheckbox_Unchecked"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The default ItemsPanel of the ListBox is the VirtualizingStackPanel. You can change it to use the StackPanel, this way you problem is solved.
Use this code:
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
<ListBox.ItemsPanel>
I suspect your problem is a result of ListBox (in SL3) now using an ItemCollectionGenerator. The concept behind this is that not all the objects found in the source data collection need to have had their corresponding instance of the DataTemplate created and added to the Visual Tree. As you scroll toward the bottom items that may soon be needed are created. Additionally items that have already be created but are now scrolled quite same way out of view can be removed. If the user scrolls up they are re-created.
If this is the case then the IsChecked state of any checkbox in this list will be lost at some point for large lists. To solve this you would need include a property in the data type to which you can bind IsChecked. Hence as ListBox re-creates items it correctly assigns the IsChecked value.

What Does this MSDN Sample Code Do? - ItemsControl.ItemTemplate

This is a XAML code sample taken from the MSDN library article for the ItemsControl.ItemTemplate property:
<ListBox Width="400" Margin="10" ItemsSource="{Binding Source={StaticResource myTodoList}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=TaskName}" />
<TextBlock Text="{Binding Path=Description}"/>
<TextBlock Text="{Binding Path=Priority}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'm looking for an explanation of the usage of the <StackPanel> element is this example.
->
Where is this panel going to exist in the ListBox?
What is its purpose in the ItemTemplate?
Can any System.Windows.Controls.Panel be used in its place, specifically a Grid?
How would I go about using a <Grid> element as the template for each item in the ListBox?
Here is the concept I am going for:
http://img151.imageshack.us/img151/7960/graphconcept.png
I have drawn the graph using a <Path> element, and there are no problems there.
I am working on the labels for the axies, and I am experimenting with the use of a <Grid> element in the ItemTemplate - but I have no idea how the grid is supposed to function in this context, and MSDN says nothing about the panel in their sample code.
My XAML for the Y-axis labels currently looks like this:
<ListBox Background="Transparent" BorderThickness="0" ItemsSource="{Binding Path=GraphLabelYData}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding Path=GraphLabelSpacing}" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="{Binding ElementName=GraphLabelYData, Path=GraphLabelMarkerLength}" />
</Grid.ColumnDefinitions>
<TextBlock HorizontalAlignment="Right" VerticalAlignment="Bottom" Text="{Binding Path=GraphLabelTag}" />
<Rectangle Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Stroke="Black" Fill="Black" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Does this look correct? Nothing shows up at run-time, but I want to make sure the XAML is modeled correctly before I start debugging the data-bindings and the code-behind.
"Where is this panel going to exist in the ListBox?" - The listbox will make one copy of it for each list item, i.e. one for each element in the myTodoList collection. So within each list item, you'll have the three labels stacked one above the other.
"What is its purpose in the ItemTemplate?" - To make it possible to show more than one control for each element in the ItemsSource. ItemTemplate, like many things in WPF, can only take one child element, so if you want multiple children, you need to specify how you want them laid out, and you do that by adding a panel (StackPanel in this case).
"Can any System.Windows.Controls.Panel be used in its place, specifically a Grid?" - You bet.
"How would I go about using a <Grid> element as the template for each item in the ListBox?" - The same way you would use a Grid anywhere else. It's no different; it's just that ItemsControl (and its descendant, ListBox) will create multiple instances of your Grid. Note, though, that inside the ItemTemplate, your DataContext will be the current list item, and therefore your {Binding}s will be relative to that list item (unless you specify otherwise with e.g. ElementName).
"Does this look correct?" - This really should be posted as a separate question, as it's unrelated to the questions about the MSDN sample, and I'm not even sure what you're trying to do. But I'll try to answer: I suspect something is wrong, because you're using the name "GraphLabelYData" two different ways. In the ColumnDefinition, as far as I can tell, you're treating GraphLabelYData as the name of a XAML element (i.e. you're looking for another control in the window/page/UserControl with Name="GraphLabelYData" or x:Name="GraphLabelYData", and reading that control's GraphLabelMarkerLength property); but in the TextBlock, you're treating GraphLabelYData as the name of a property on the current collection item. I suspect one of those isn't right.

Resources