WPF Toolkit Chart - Collapsing Chart Points - wpf

I have a chart with 1000s of points of data and am wondering how to remove the data points? They slow the whole process down considerably. I researched about having to change the style, is there another way?
Removing (collapsing) DataPoints in a LineSeries?
<Grid>
<chartingToolkit:Chart
Width="Auto" Height="Auto"
Background="Transparent" Panel.ZIndex="3">
<chartingToolkit:LineSeries Title="Symbol" Background="Transparent"
IndependentValueBinding="{Binding Path=Key}"
DependentValueBinding="{Binding Path=Value}"
ItemsSource="{Binding Path=SymbolData}"
DataContext="{Binding}">
<chartingToolkit:LineSeries.DataPointStyle>
<Style TargetType="{x:Type chartingToolkit:LineDataPoint}">
<Setter Property="Background" Value="Red"/>
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</chartingToolkit:LineSeries.DataPointStyle>
</chartingToolkit:LineSeries>
</chartingToolkit:Chart>
</Grid>
I thought the code above would've worked, but apparently not...
Further research, even this answer did not work : /
Removing markers from silverlight line or area series
Cheers for the help.

Setting the point styles to Collapsed won't solve your issue as the objects will still be in the visual tree affecting rendering time. Since you have set up bindings for the data points, the only way to remove them is to remove your business objects that they are bound to.
Also, since you're talking about performance, it's worth noting that the WPF toolkit's performance is much worse than some other free charting components. See this article on charting component's performance comparison - it was written comparing Silverlight versions, but according to my experience it holds for WPF as well. Using Visiblox, DD3 or Visifire would probably significantly improve the performance of your charts. (Full disclosure: I have been involved in developing in Visiblox)

Related

How to get always the same instance of UserControl loaded via DataTemplate?

One ContentControl is used to load one of two UsersControls in resources via datatemplate.
It works fine but the constructor of every usercontrol is always called when navigating between them. How can I load always the same instance of the usercontrol (one instance for UserControl1 and one instance for Usercontrol2). I know that the tabcontrol can achieve that but how I can do it in my scenario without tabcontrol.
Resources:
<UserControl.Resources>
<DataTemplate x:Key="UserControl1">
<local:UserControl1 />
</DataTemplate>
<DataTemplate x:Key="UserControl2">
<local:UserControl2 />
</DataTemplate>
</UserControl.Resources>
ContentControl:
<ContentControl x:Name="ContentControl" Background="White">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Style.Triggers>
<DataTrigger Binding="{Binding CurrentView,
ElementName=UserControl1}" Value="UserControl1">
<Setter Property="ContentTemplate" Value="{StaticResource UserControl1}" />
</DataTrigger>
<DataTrigger Binding="{Binding CurrentView, ElementName=UserControl2}" Value="UserControl2">
<Setter Property="ContentTemplate" Value="{StaticResource UserControl2}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
How can I load always the same instance of the usercontrol (one instance for UserControl1 and one instance for Usercontrol2)
You can hold the instances as Resources and host them inside a ContentPresenter, instead of creating a new instance everytime the DataTemplate is used:
<UserControl.Resources>
<local:UserControl1 x:Key="UserControl1Instance" />
<local:UserControl2 x:Key="UserControl2Instance" />
<DataTemplate x:Key="UserControl1">
<ContentPresenter Content="{StaticResource UserControl1Instance}" />
</DataTemplate>
<DataTemplate x:Key="UserControl2">
<ContentPresenter Content="{StaticResource UserControl2Instance}" />
</DataTemplate>
</UserControl.Resources>
How can I load always the same instance of the usercontrol
You should not be concerned about that. There's nothing in your post that explains why you are concerned about the constructor being called multiple times, but that should be a complete non-issue. If it's an issue, then you have something wrong with your design.
"View" objects, such as windows, user controls, and indeed every UIElement that goes into presenting the program's state to the user, should not have any operations within them except that strictly needed to present the state to the user. WPF will instantiate and discard your specific instances as needed to handle the current state of the program. If it's in any way a problem for more than one instance of a user control to exist at a time, or for more than one instance to be created and/or discarded over the course of running the program, then the design of the program is fundamentally broken and should be fixed.
If you run into any problems trying to accomplish that, of course feel free to post a question about that. Be sure to include a good Minimal, Reproducible Example, along with any details about what specifically you need help with.
And of course, to start with, you should read everything you can find on the MVVM design pattern, if you haven't already. WPF has a steep learning curve when using the framework correctly, but it's even harder to use when you're not using it correctly.

VisualBrush using MediaElement in a Style

I have a UserControl that converts a text to a shape. I can then Stroke it or Fill it with a Brush. When I try to use a Visual Brush with a MediaElement (video) as the Source I am running into problems. When I do it directly in the XAML as below:
<custom:ExtendedTextBlock Text="Video Filled Text" FontFamily="Arial Black" FontSize="60">
<custom:ExtendedTextBlock.Fill>
<VisualBrush>
<VisualBrush.Visual>
<MediaElement Source="assets\1267066.mp4" Width="596" Height="366" LoadedBehavior="Play" Stretch="UniformToFill" MediaEnded="MediaElement_MediaEnded" MediaFailed="MediaElement_MediaFailed" MediaOpened="MediaElement_MediaOpened" />
</VisualBrush.Visual>
</VisualBrush>
</custom:ExtendedTextBlock.Fill>
</custom:ExtendedTextBlock>
It works great. The problem appears when I try to create a Style using the same information:
<Style x:Key="VideoFill" TargetType="{x:Type custom:ExtendedTextBlock}">
<Setter Property="StrokeThickness" Value="2" />
<Setter Property="Stroke" Value="Black" />
<Setter Property="Fill">
<Setter.Value>
<VisualBrush>
<VisualBrush.Visual>
<MediaElement Source="assets/1267066.mp4" Width="596" Height="366" LoadedBehavior="Play" LoadedBehavior="Play" Stretch="UniformToFill" MediaEnded="MediaElement_MediaEnded" MediaFailed="MediaElement_MediaFailed" MediaOpened="MediaElement_MediaOpened" />
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</Style>
I get no fill. No MediaOpened is thrown, no MediaFailed is thrown. It just doesn't render the fill. Using this same method with a SolidColorBrush, LinearGradientBrush, ImageBrush all works perfectly. Can anyone tell me what is going on here?
I've seen all sorts of examples of MediaElement not playing nicely with other WPF components, I don't think the dev team did their integration testing quite as comprehensively with that one as perhaps they did with other things. This particular case appears to be a bug I've seen crop up a few times where an element used in a style is created and then destroyed several times during initialization. MediaElement seems to be doing some type of deferred processing, gets confused and winds up thinking that it's no longer being used. The solution, believe it or not, is to simply set UnloadedBehavior="Play" as well.
Personally though I tend to avoid letting the XAML framework control things like this. My own approach with MediaPlayer is to make each instance a static resource, set both LoadedBehavior and UnloadedBehavior to "Manual" and control playback manually with a Blend behavior containing dependency properties that I bind back to my view models. This provides all the advantages of complete code-driven control of the media element without breaking MVVM and without having to cross your fingers and hope that the framework behaves itself.

How to display a MessageBox when wrong input is given and reverting the old value of TextBox using MVVM in WPF

I have been using WPF and its built in validation controls for quiet sometime. I was going through an excellent article in codeproject whose link is given below
http://www.codeproject.com/KB/WPF/wpfvalidation.aspx
I am having a requirement from one of our clients which I have not been able to chieve using MVVM in WPF.
The problem is as follows :
There is a TextBox which accepts only numbers.
When the user enters any value other than numbers I have to display an error to him. The error should
highlight the TextBox, provide a ToolTip
display an error in MessageBox
revert the TextBox to its previous value
For example when the TextBox is loaded, it might have an initial value say 10
. Then the user enters some wrong value say "aa".
Now I have to display a MessageBox saying "Wrong value" and then revert the value back to 10.
There are lot of articles and ways to display error in WPF say by using ErrorTemplate and so on.
<Style TargetType="{x:Type TextBox}">
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Right"
Foreground="Orange"
FontSize="12pt">
!!!!
</TextBlock>
<Border BorderBrush="Green" BorderThickness="1">
<AdornedElementPlaceholder />
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors)[0].ErrorContent}">
</Setter>
</Trigger>
</Style.Triggers>
</Style>
But how do I revert the value and display a MessageBox. I know it can be displayed using an event in code-behind file but I dont want to write any logic in my code behind file. I want to achieve this functionality using MVVM
A sample illustration will be really helpful!!
the answer to your 2nd question: build a messageboxservice and just call it from your viewmodel. you can find mvvm messageboxservices in all wpf frameworks. look at cinch for example.
the undo redo thing, hmm its built in in wpf, so strg+z will work. but i dont know yet how to get it work with mvvm :)
Hey people finally I solved the problem. Its based on this
StackOverFLow Solution
The solution is very simple. I call the Validator on losing focus from TextBox. The validator return me a Validation Result.Based on the result I can take some action.
I used attached behaviour for this. I have written a trigger which checks if Validation.HasError is true or not. If it is true, then it assigns some dummy value to my attached property. While assigning I will have TextBoxBase under my control. Using this I just call the Undo() function and it solves my problem.

Custom panel with alternate background

I'd like to create a simple custom panel to layout children in a business form fashion. Ideally I'd like my markup to look like this:
<Panels:FormPanel>
<TextBlock Text="Name:"/>
<TextBox />
<TextBlock Text="Address"/>
<TextBlock Text="Unknown"/>
<TextBlock Text="City"/>
<TextBox HorizontalAlignment="Stretch"/>
<TextBlock Text="State"/>
<ComboBox/>
<TextBlock Text="Country"/>
<StackPanel>...</StackPanel>
</Panels:FormPanel>
The panel will layout controls in two columns labels on the left side and values on the right.
I have no problem laying out my controls. The problem is that I also need to alternate background for the rows to create stripes for easier reading.
Any ideas how can this be done?
This doesn't directly answer your question, but you could consider this as another solution to the underlying problem.
Take a look at http://wpg.codeplex.com/. I used a similar property-grid-like control in Windows Forms that was modified to understand custom attributes on my business objects.
Now, in WPF, I would think something similar would work really well if you follow the MVVM pattern and you decorate your ViewModel with attributes that such a property grid understands. Then you don't need to explicitly define the fields like you show above.
You could have a ViewModel:
class PersonViewModel
{
[DisplayName("Name")] // The property Grid uses this the Textblock text
[IsRequired] // The property grid could do validation on the field
[Visible]
public string Name { get; set; }
public long InvisibleSystemField { get; set; } // Not shown
}
And then you'd only have Views (Xaml files) like this:
<myCommon:PropertyGrid DataContext={Binding}/>
It could simply use it's DataContext as the starting point for reflection.
OK I'll stop there for now :)
I'm working on a WPF powered LOB application and I'll possibly build something like this in future.
Implementing a custom panel is not actually that difficult. You have to override two methods, Measure and Arrange. Google for "wpf custom panel" to get some articles about that.
What I would suggest you do to get the behavior exactly as you required in the question is extend Windows.Controls.Grid. Your custom grid could then have two columns by default that you initialize in the constructor and you can programmatically set the Grid.Column and Grid.Row properties on the child controls.
Also worth looking at could be the ItemsControl. It does have support for alternatively colored rows. This example (from MSDN) shows how to use it:
<Grid>
<Grid.Resources>
<Style x:Key="alternatingWithTriggers" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Blue"/>
<Setter Property="Foreground" Value="White"/>
<Style.Triggers>
<Trigger Property="ListBox.AlternationIndex" Value="1">
<Setter Property="Background" Value="CornflowerBlue"/>
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="ListBox.AlternationIndex" Value="2">
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="Foreground" Value="Navy"/>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Resources>
<ListBox AlternationCount="3" ItemsSource="{StaticResource data}"
ItemContainerStyle="{StaticResource alternatingWithTriggers}">
</ListBox>
</Grid>
You could then specify a template for the items that includes a Label and a TextBox, but getting this to work could be fiddly.
Here's one final thing I'll suggest:
XAML Powertoys include features that allow you to generate business forms from ViewModels, ViewModels from Models and much more. You might need to modify the source to get alternating row colors though.
Good luck!

How to change WPF Listbox/ListBoxItem DataTemplate for selected item WITHOUT affecting style & theming?

This question is very similar to Change WPF DataTemplate..., which I have read and implemented. It worked beautifully at first, but I ran into a problem with it.
That problem is that, when using themes in your application such as those in the WPF Futures project (e.g. Expression Dark), the ListBoxItems all revert back to the default WPF styling. This breaks the theme for those elements and, for example, produces black text on black background where the text would otherwise be white. This also affected my TreeView, and presumably would affect other similar controls.
I think this is because conflicting styles are being set for ListBox.ItemContainerStyle--one from the theme and one for switching data templates.
I've looked around for other solutions, but haven't found anything yet. Here are the leads or ideas I've had so far:
Subclassing DataTemplateSelector and setting it to ListBox.ItemTemplateSelector. (The current best bet).
Somehow, somewhere use a Trigger, DataTrigger, or EventTrigger.
Give up on themes.
Somehow hack the functionality I want into the theme.
Somehow make my custom ItemContainerStyle somehow inherit it's colors and eye candy from the theme's style. (I tried it briefly, and it didn't work.)
Here is my ListBox and related pieces:
<Window.Resources>
<DataTemplate x:Key="NormalTemplate">
...
</DataTemplate>
<DataTemplate x:Key="SelectedTemplate">
...
</DataTemplate>
</Window.Resources>
<ListBox x:Name="RegisterListBox" Grid.Row="0"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Adjustments}">
<!-- this is from the post referenced above -->
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="ContentTemplate" Value="{StaticResource NormalTemplate}"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
The Listbox.DataContext is set in code to enable the ItemsSource binding.
Any ideas how I can achieve the kind of functionality described above while maintaining seamless support for themes?
Have you tried doing something like this?
<ListBox.ItemContainerStyle>
<Style
TargetType="{x:Type ListBoxItem}"
BasedOn="{StaticResource {x:Type ListBoxItem}}"> <=====
...
The idea is that the framework will first go look for a style with a key equal to typeof(ListBoxItem), it will find it in the themes, and then your style will just extend the themed one with your specific details.

Resources