Why VirtualizingStackPanel.IsVirtualizing in silverlight datagrid threw an exception? - silverlight

i added VirtualizingStackPanel in my datagrid for on-demand load records to get rid of too long loading time taken to display all the records.
<sdk:DataGrid VirtualizingStackPanel.VirtualizationMode="Recycling" VirtualizingStackPanel.IsVirtualizing="True" AutoGenerateColumns="False"
HorizontalAlignment="Center" Name="dgrGrid" Width="430" Height="270" Grid.Row="1" Margin="10,10,10,10" Loaded="dgrGrid_Loaded">
but when i tried to load data on the datagrid, got this error...can someone point me where to correct this error? thanks in advance.
{System.Windows.Markup.XamlParseException: Set property 'System.Windows.Controls.VirtualizingStackPanel.IsVirtualizing' threw an exception. [Line: 37 Position: 123] ---> System.NotSupportedException: Cannot set read-only property 'System.Windows.Controls.VirtualizingStackPanel.IsVirtualizing'.
at MS.Internal.XamlMemberInfo.SetValue(Object target, Object value)
at MS.Internal.XamlManagedRuntimeRPInvokes.SetValue(XamlTypeToken inType, XamlQualifiedObject& inObj, XamlPropertyToken inProperty, XamlQualifiedObject& inValue)
--- End of inner exception stack trace ---

You should remove the VirtualizingStackPanel.IsVirtualizing="True" as the exception message states that it is a read-only property. SL datagrid uses already uses virtualization for performance optimization, so you just need to set the virtualization mode you want it to utilize.
Your DataGrid will then look like...
<sdk:DataGrid
VirtualizingStackPanel.VirtualizationMode="Recycling"
AutoGenerateColumns="False"
HorizontalAlignment="Center"
Name="dgrGrid"
Width="430"
Height="270"
Grid.Row="1"
Margin="10,10,10,10"
Loaded="dgrGrid_Loaded">

Related

How to use a RibbonGallery with a RibbonComboBox

So I wanted to add a RibbonCombobox to my Ribbon in WPF. For some reason, RibbonCombobox does not have a selectionchanged event. I read that you should use a RibbonGallery for selection change event so I implemented this
<RibbonComboBox Label="Equations" x:Name="EquationListComboToolbar" ItemsSource="{Binding}">
<RibbonGallery x:Name="EquationListComboboxGallery" SelectedValue="{Binding XPath=.}" />
</RibbonComboBox>
Behind the scene the binding is done like this.
EquationListComboToolbar.DataContext = ViewModel.EquationNames;
this.Bind(ViewModel, vm => vm.SelectedEquation, v => v.EquationListComboboxGallery.SelectedItem).DisposeWith(cleanup);
Observable.FromEventPattern(EquationListComboboxGallery, nameof(EquationListComboboxGallery.SelectionChanged)).Subscribe(e => ViewModel.SelectEquation(EquationListComboboxGallery.SelectedItem?.ToString()));
At runtime I get the following error
"An unhandled exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll
Items collection must be empty before using ItemsSource." When the app initalizez. I know it's something about the Gallery but I can't figure out what is the problem and how can I achieve this.
As I was suggested, I already tried the answer that was suggested
<RibbonComboBox Label="Equations" x:Name="EquationListComboToolbar" ItemsSource="{Binding}">
<RibbonComboBox.ItemTemplate>
<DataTemplate>
<RibbonGallery x:Name="EquationListComboboxGallery" SelectedValue="{Binding XPath=.}" />
</DataTemplate>
</RibbonComboBox.ItemTemplate>
</RibbonComboBox>
Doing this, will make by binding imposible
Ah, yes. The Microsoft ribbon library is lots of fun. Luckily I've been down this road before. Here's a working example of a RibbonComboBox from one of my applications, complete with RibbonGallery:
<RibbonComboBox DropDownHeight="400">
<RibbonGallery MaxColumnCount="1" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectedItem="{Binding MySelectedItemProperty}">
<RibbonGalleryCategory ItemsSource="{Binding MyItemsSourceProperty}"/>
</RibbonGallery>
</RibbonComboBox>
I'm not entirely sure this is the only way to do things, but I know this way works. Note that I set ItemsSource on the RibbonGalleryCategory, not the RibbonComboBox itself. It might be possible to use the RibbonGallery without a RibbonGalleryCategory, in which case you would set ItemsSource on RibbonGallery, but I've not tested this.
Note you also have the ability to add multiple galleries categories to a single RibbonComboBox like so:
<RibbonComboBox DropDownHeight="400">
<RibbonGallery MaxColumnCount="1" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectedItem="{Binding MySelectedItemProperty}">
<RibbonGalleryCategory ItemsSource="{Binding MyFirstItemsSourceProperty}"/>
<Separator/>
<RibbonGalleryCategory ItemsSource="{Binding MySecondItemsSourceProperty}"/>
</RibbonGallery>
</RibbonComboBox>
The above lets you show multiple lists in the same drop down and allows the user to select a single item from any list. Functionality like this is probably why RibbonGalleryCategory exists in the first place.

How to keep bindings when serializing a WPF usercontrol into an XElement

I'm trying to serialize a custom WPF user control that features a grid with a textblock that is bound to a dependency property named "Frequency". The snippet that defines the textblock is as follows (the definition of the user control is quite lengthy to post it here!):
<TextBlock x:Name="FrequencyText" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"
FontFamily="Arial Rounded MT"
Foreground="White" FontSize="10" FontWeight="DemiBold" Margin="3"
TextBlock.Text="{Binding Frequency, ElementName=FrequencyButtonControlA, Path=Frequency}"
TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Left" />
I'm working on an editor tool that enables the user to arrange some custom controls into a canvas and change their properties and I need to provide the user with the capability to clone an existing element. In order to do this, I'm serializing the control into an XElement and instantiating a new one afterwards. The code to perform the serialization is as follows:
var contentXaml = (commsPanelItem.Content != null) ? XamlWriter.Save(commsPanelItem.Content) : string.Empty;
var serializedItem = new XElement(
"CommsPanelItem",
new XElement("Type", commsPanelItem.GetType().ToString()),
new XElement("Left", Canvas.GetLeft(commsPanelItem.UIElement)),
new XElement("Top", Canvas.GetTop(commsPanelItem.UIElement)),
new XElement("Width", commsPanelItem.Width),
new XElement("Height", commsPanelItem.Height),
new XElement("zIndex", Panel.GetZIndex(commsPanelItem.UIElement)),
new XElement("Content", contentXaml),
commsPanelItem.GetAttributesForSavingPanelInConfigurator() as XElement);
return serializedItem;
The problem I'm having is that, when serializing the textblock, the "Text" field doesn't preserve the binding to the "Frequency" dependency property, it just gets exported with the value assigned by the user ("131.5" in the following example):
TextBlock Text="131.5" FontFamily="Arial Rounded MT" FontWeight="SemiBold" FontSize="10" Foreground="#FFFFFFFF" TextAlignment="Center" Name="FrequencyText" Margin="3,3,3,3" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2"
My question is: is there any way to be able to serialize dependency property's binding instead of the actual value?
Thanks in advance!
Use the "GetBinding" method found on FrameworkElements instead of pulling its value:
BindingExpression bindingExpression = myTextBox.GetBindingExpression(TextBox.TextProperty);
Then you can probably serialize the BindingExpression.

Adding Event Handlers to WPF DataGrid throws NullReferenceException

I'm not sure what's wrong with the DataGrid I've written. The contents show up correctly but when I try to add in a OnSelectionChanged event handler, sth odd happens.Please help me!
Firstly, no problems below:
<DataGrid ItemsSource="{Binding XPath=services/service}" AutoGenerateColumns="False" Padding="2">
<DataGrid.Columns>
<DataGridTextColumn Header=" Service Name " Binding="{Binding XPath=name}" Width="300"/>
<DataGridTextColumn Header=" Status " Binding="{Binding XPath=status}" />
</DataGrid.Columns>
</DataGrid>
Here services/service are from my external XML file. I used XmlDataProvider resource in the document. In that XML, some 'services' tag has many 'service' children elements; some 'services' tag does not have any children at all (wondering if this is the cause of problem).
So the resultant UI is some of the datagrids contain all the rows and columns. some of the datagrids only show the headers.
Now I add in this:
<DataGrid ItemsSource="{Binding XPath=services/service}" AutoGenerateColumns="False" Padding="2"
SelectionChanged="DataGrid_SelectionChanged">
And put in a empty method on the code:
private void DataGrid_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
}
Now I execute, and an exception is thrown
System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=ForeFront Support Monitor 2
StackTrace:
at FSM.MainWindow.System.Windows.Markup.IStyleConnector.Connect(Int32 connectionId, Object target) in h:\Personal\Visual Studio 2010\Projects\ForeFront Support Monitor 2\ForeFront Support Monitor 2\MainWindow.xaml:line 42
at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)
at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlObjectWriter objectWriter)
at System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(DependencyObject container, IComponentConnector componentConnector, IStyleConnector styleConnector, List1 affectedChildren, UncommonField1 templatedNonFeChildrenField)
at System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren)...
XML binding to WPF DataGrid can be torturous.
Try binding XML in a different way (like a object model)... How to bind xml to the WPF DataGrid correctly?
And then check if selection changed event fires correctly?

WPF Binding: Waiting for ItemsSource

I have a problem with the following binding:
<telerik:RadComboBox ItemsSource="{Binding Source={StaticResource TemplateDataSource}, Path=Templates}"
SelectedValue="{Binding Template}"
SelectedValuePath="Id"
DisplayMemberPath="Title"
Margin="0">
</telerik:RadComboBox>
All my data is loaded async via WCF data services.
From time to time I get the following error (which I could trace back to the above binding)
Specified argument was out of the range of valid values.
Parameter name: index
Now I guess it has something to do with the entity providing the SelectedValue (Template) being loaded before the ItemsSource. Could this be? Is there a solution to this problem, like waiting for the ItemsSource to load?
Thanks for any help in advance!
Try to write Dummy converter on SelectedValue="{Binding Template}"
You can then debug this converter to find out real cause of error.

Silverlight Label content binding problems

I'll preface this and say that I'm new to Silverlight development by about week so I'm most likely doing it wrong...
Anyway I have a Label and a TextBox done up thusly in XAML:
<dataInput:Label Target="{Binding ElementName=JobCode}" Height="18" HorizontalAlignment="Left" Margin="15,7,0,0" Name="lableJobCode" VerticalAlignment="Top" Width="250" FontWeight="Bold" Grid.Column="1" />
<TextBox Height="23" Text="{Binding SelectedRole.Job_Code}" HorizontalAlignment="Left" Margin="15,31,0,0" Name="JobCode" VerticalAlignment="Top" Width="277" Grid.Column="1" IsReadOnly="{Binding IsNotAdmin}" />
Everything works great, the only issue I have is that the binding I'm doing on the IsReadOnly attribute which goes to a boolean in my ViewModel which is set based on a call to an authentication service, is now overriding the label Content to the name of my ViewModel property: IsNotAdmin. I can't seem to find a way to specify which data binding source to pull the label content MetaData from. Maybe I'm missing something on how to manipulate control editablity/visibility from my ViewModel.
--Update: The data source class that the TextBox is bound to is as follows (for the relevant parts):
public class RoleSummary {
[Display(Name= "Job Code (To be Completed by HR):")]
public string Job_Code { get; set; }
Without the binding to the IsReadOnly attribute the Label displays the text from the data annotation just fine. When I add the binding it displays "IsNotAdmin"
can you post more of your code? I'm not entirely sure what it is that you're trying to make happen so it's hard to propose a solution.
I assume you're trying to create a text entry element that has validation performed on it (hence the label) -- but what exactly is the label supposed to be showing for it's content?
EDIT: I figured this out. The label control by default looks through all the properties in its datacontext looking for metadata it can use. For whatever reason it decided to use the metadata for the IsNotAdmin property in your code (even though you didn't set it manually, I assume that the Display metadata gets a default value of the property name), and so you get that for the text of the label.
Microsoft put in a property specifier into the data controls so you can tell it which property it should use for the metadata lookup: PropertyPath
Try it like this:
<dataInput:Label Target="{Binding ElementName=JobCode}" PropertyPath="SelectedRole.Job_Code" Height="18" HorizontalAlignment="Left" Margin="15,7,0,0" Name="lableJobCode" VerticalAlignment="Top" Width="250" FontWeight="Bold" Grid.Column="1" />
<TextBox Height="23" Text="{Binding SelectedRole.Job_Code}" HorizontalAlignment="Left" Margin="15,31,0,0" Name="JobCode" VerticalAlignment="Top" Width="277" Grid.Column="1" IsReadOnly="{Binding IsNotAdmin}" />
As long as your datacontext is right (which it should be) this should work for you -- it worked in my sample I reconstructed from your code.

Resources