Binding question

Oystein Bjorke 10 year бұрын 0
This discussion was imported from CodePlex

MarcBra wrote at 2012-05-11 02:46:

Hi!

Disclaimer:

I like OxyPlot a lot, thank you very much for your effort!

My question:

I have a fairly simple binding scenario and face some issues at the moment. It's probably simple and I don't expect a detailed answer, but a hint what to look at, best practice, or something similiar would be very helpful.

I have a UserControl which contains a plot and a couple of series, that are databound by their ItemsSource property. It's a MVVM application and the codebehind of the control is blank. If I have several instances of the UserControl bound to different ViewModels, the Plots all display the same data, which is the data of the Plot that is instantiated at first, instead of the data they are actually bound to.

Why is this and what do I have to do? I am aware of the fact that I have to manually update the plots, but it doesn't work in that case and shouldn't be an issue in this case, because the data is existent at the time the control is instantiated.

 

Thank you very much for your work and your help in advance!

 

Cheers, Marc


seveland12 wrote at 2012-05-11 15:05:

Are you setting the DataContext of each UserControl properly? It sounds like your UserControls are all bound to the same data, which, if I understand your situation correctly, is not what you intend.


MarcBra wrote at 2012-05-12 07:56:

Hi seveland, thanks for your reply.

Unfortunately, that is not the problem. This is my UserControl XAML: 

 

<UserControl x:Class="Inca.App.Controls.SpatialStressAnalysisView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             xmlns:oxy="clr-namespace:OxyPlot.Wpf;assembly=OxyPlot.Wpf" 
             xmlns:IncaControls_Converter="clr-namespace:Inca.App.GUILogic">
    <UserControl.Resources>
        <IncaControls_Converter:BoolToVisibility x:Key="BoolToVisibility"/>
    </UserControl.Resources>
    <DockPanel> 
        <TabControl Margin="10">
                    <TabItem Header="Laminate coordinate system (LCS)">
                        <Grid Margin="10" >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="300">
                                </ColumnDefinition>
                                <ColumnDefinition></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <DockPanel Grid.Column="0">

                                <GroupBox DockPanel.Dock="Top" Header="Plot graphs" Margin="0,0,0,10">
                                    <StackPanel Orientation="Vertical" Margin="5">
                                        <CheckBox Content="XZ shear stress" Name="chkVisibilityXZ" IsChecked="True"></CheckBox>
                                        <CheckBox Content="YZ shear stress" Name="chkVisibilityYZ" IsChecked="True"></CheckBox>
                                        <CheckBox Content="Z normal stress" Name="chkVisibilityZ" IsChecked="True"></CheckBox>
                                <Button Click="Button_Click">Refresh</Button>
                            </StackPanel>
                                </GroupBox>
                            <ScrollViewer Grid.Row="1" >
                                <DataGrid x:Name="grid" ItemsSource="{Binding StressPointsLCS}"></DataGrid>
                            </ScrollViewer>
                            </DockPanel>


                    <oxy:Plot Grid.Column="1" x:Name="plot" Subtitle="{Binding LaminateName}">

                                <oxy:Plot.Axes>
                                    <oxy:LinearAxis Position="Left" MajorGridlineStyle="Solid" MinorGridlineStyle="Solid" MinorGridlineColor="#11000000" Title="Stress [N/mm�]" />
                                    <oxy:LinearAxis Position="Bottom" MajorGridlineStyle="Solid" MinorGridlineStyle="Solid" MinorGridlineColor="#11000000" Title="z [mm]" />
                                </oxy:Plot.Axes>
                                <oxy:Plot.Series>
                                    <oxy:LineSeries Title="XZ Shear Stress" 
                                                        Visibility="{Binding IsChecked, ElementName=chkVisibilityXZ, Mode=OneWay, Converter={StaticResource ResourceKey=BoolToVisibility}}" 
                                                        DataFieldX="ThicknessCoordinate" DataFieldY="ShearStressParallelTransverse" Color="DarkBlue" StrokeThickness="2" ItemsSource="{Binding StressPointsLCS}"/>
                                    <oxy:LineSeries Title="YZ Shear Stress" 
                                                        Visibility="{Binding IsChecked, ElementName=chkVisibilityYZ, Mode=OneWay, Converter={StaticResource ResourceKey=BoolToVisibility}}" 
                                                        DataFieldX="ThicknessCoordinate" DataFieldY="ShearStressTransverseTransverse" Color="LightBlue" StrokeThickness="2" ItemsSource="{Binding StressPointsLCS}"/>
                                    <oxy:LineSeries Title="Z Normal Stress" 
                                                        Visibility="{Binding IsChecked, ElementName=chkVisibilityZ, Mode=OneWay, Converter={StaticResource ResourceKey=BoolToVisibility}}" 
                                                        DataFieldX="ThicknessCoordinate" DataFieldY="NormalStressTransverse" Color="Green" StrokeThickness="2" ItemsSource="{Binding StressPointsLCS}"/>
                                </oxy:Plot.Series>
                            </oxy:Plot>
                        </Grid>
                    </TabItem>           
                </TabControl>
    </DockPanel>
</UserControl>



As you can see the DataGrid in my control displays the same data as the plot. In this table, the datapoints are displayed correctly, so the DataContext is obviously correct! For testing purposes I bound the Subtitle of the Plot to a property on the ViewModel and it is displayed correctly, so the DataContext of the Plot itself is obviously correct as well. This is why I don't really know, what the issue is... The UserControl itself is used within a TabControl again (1 per TabItem). Could that play a role? Or any other ideas?

 

Thanks, Marc

 

I have a DataTemplate for the ViewModel that belongs to the control and bind the ViewModel directly to the content of a ContentPresenter (which all 

objo wrote at 2012-05-13 22:16:

I added some examples in the new Examples/WPF/WpfExamples application. See the three examples at the bottom - the first one (with a UserControl) is working, the two others (using DataTemplates) are not - I think this is related to the problem you are seeing. I have tried debugging, but not found out what is going on yet. I will not have time to look at this the coming week, maybe someone else can figure it out?

I think there is a bug in the OxyPlot.Wpf.ItemsSeries - the OnItemsSourceChanged is only called for the first plot. And it is very strange that the two plots are sharing the same collection of points...


MarcBra wrote at 2012-05-14 02:05:

Thanks, objo! I haven't figured out anything helpful so far, just a minor remark after a first look: The third example is linked to the same window as the second in MainWindow.xaml.cs:

 

new Example(typeof(UserControlDemo.MainWindow), null, "Demonstrates a Plot in a UserControl."),
new Example(typeof(UserControlDemo.MainWindow2), null, "... UserControl in a DataTemplate."),
new Example(typeof(UserControlDemo.MainWindow2), null, "... a DataTemplate.")

Anybody who wants to test it would find out himself quickly, but might make life a little easier, if I mention.


MarcBra wrote at 2012-05-14 04:41:

So, I couldn't figure out a solution yet, but the problem at least:

When specified in a DataTemplate, only one instance of the UserControl is created by the WPF. If you click through the TabItems, you always see the same instance of the UserControl and only the DataContext is changed. This is obviously meant to be and has nothing to do with this particular case. This is why the Title is displayed correctly, but the Series are not updated correctly. To make it work, the control would have to update everything including the Series on the DataContextChanged event. I don''t overlook all of the OxyPlot system yet, so I'm not sure about how.

A possible workaround is using a modified TabControl, which behaves differently or specifying the control as a ressource in a ResourceDictionary and using the x:Shared="false" attribute on the control (haven't tried it yet).

I'm out of time right now, but I'm sure we're getting there sooner or later.

 

Cheers, Marc


tstojano wrote at 2012-09-02 18:27:

I'm seeing the exact same behaviour with my MVVM usage of a oxyplot control defined within a datatemplate.

Oxyplot is always graphing the points from the first oxyplot control instead of the oxyplot control corresponding to the active tab.  As per Marc, my datacontext is definitely set correctly as the graph title is changing as expected.  Also, I verified in snoop that the Series[0].ItemsSource is correct.

I tried with no luck
- latest oxyplot (August 31 - 2012.3.135.1)
- moving the oxyplot control to a resource with x:Shared="false".

I couldn't find any defects raised in the issue tracker either.  Does anyone have a workaround/fix for this?

 

Cheers

Stoj


objo wrote at 2012-09-02 18:34:

thanks for reminding me. It is now added as issue 10000!

http://oxyplot.codeplex.com/workitem/10000

I have not had time to look into this issue myself - I hope someone else has some spare time!