在代码隐藏中使用以 xaml 声明的自定义“样式”会引发运行时错误

本文关键字:样式 自定义 运行时错误 声明 隐藏 代码 xaml | 更新日期: 2023-09-27 18:37:06

我在 xaml 中声明了一个样式,我需要在代码隐藏中使用并应用于用户控件,当我使用相同的样式两次时,会引发以下错误:

元素已具有逻辑父级。它必须与旧的分离 父项在附加到新项之前。

我做错了什么?我需要在代码隐藏中创建相同用户控件类型的多个控件,并对其应用一个相同的Style

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking"
    xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
    x:Class="MyChartControl.MainWindow"
    Title="MainWindow" Height="655" Width="1020">
<Window.Resources>
   <Style x:Key="SciChartSurfaceStyle" TargetType="{x:Type s:SciChartSurface}">
        <Setter Property="XAxis">
            <Setter.Value>
                <s:DateTimeAxis Visibility="Visible"
                                TextFormatting="dd/MM/yyyy"
                                SubDayTextFormatting="dd/MM/yyyy HH:mm:ss.fff"
                                GrowBy="0.02, 0.02"/>      
            </Setter.Value>
        </Setter>
        <Setter Property="YAxis">
            <Setter.Value>
                <s:NumericAxis  AxisAlignment="Right"
                                Visibility="Visible" 
                                TextFormatting="{Binding YAxisFormatting}" 
                                GrowBy="0.02, 0.02" 
                                AutoRange="Always"/>
            </Setter.Value>
        </Setter>
        <Setter Property="ChartModifier">
            <Setter.Value>
                <s:ModifierGroup>
                    <s:RubberBandXyZoomModifier IsAnimated = "False" IsXAxisOnly = "True" ExecuteOn = "MouseRightButton"/>
                    <s:ZoomPanModifier XyDirection="XYDirection" ClipModeX = "ClipAtExtents" ExecuteOn ="MouseLeftButton" />
                    <s:MouseWheelZoomModifier XyDirection = "XYDirection"/>
                    <s:ZoomExtentsModifier IsAnimated = "False" ExecuteOn = "MouseDoubleClick" />
                    <s:XAxisDragModifier  DragMode = "Scale"/>
                    <s:CursorModifier SourceMode="AllSeries"  UseInterpolation="True"/>
                    <s:LegendModifier ShowLegend="True" LegendPlacement ="Inside" GetLegendDataFor="AllSeries" Margin="10"/>
                     <!--<s:SeriesSelectionModifier ReceiveHandledEvents="True">
                            <s:SeriesSelectionModifier.SelectedSeriesStyle>
                                <Style TargetType="s:BaseRenderableSeries">
                                    <Setter Property="SeriesColor" Value="White"/>
                                    <Setter Property="PointMarkerTemplate">
                                        <Setter.Value>
                                            <ControlTemplate>
                                                <s:EllipsePointMarker Fill="#FF00DC" Stroke="White" Width="7" Height="7"/>
                                            </ControlTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </Style>
                            </s:SeriesSelectionModifier.SelectedSeriesStyle>
                        </s:SeriesSelectionModifier>-->

                </s:ModifierGroup>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="32" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <StackPanel Grid.Row="0" Orientation="Horizontal" Background="Black">
        <TextBlock Text="Dataseries Type:" Margin="5,0" VerticalAlignment="Center" FontSize="12" Foreground="White"/>
        <ComboBox x:Name="ComboBox_ChooseSeriesType" MinWidth="140" Margin="5,3" VerticalContentAlignment="Center"/>
        <TextBlock Text="Theme:" Margin="5,0" VerticalAlignment="Center" FontSize="12" Foreground="White"/>
        <ComboBox x:Name="ComboBox_ChooseTheme" MinWidth="140" Margin="5,3" VerticalContentAlignment="Center"/>
    </StackPanel>

        <dxdo:LayoutGroup Grid.Row="1" x:Name="LayoutGroup" Orientation="Vertical">
            <!--<dxdo:LayoutPanel Name="Panel1">
                <s:SciChartSurface Name="Surface1" Style="{StaticResource SciChartSurfaceStyle}"></s:SciChartSurface>
            </dxdo:LayoutPanel>-->


    </dxdo:LayoutGroup>

    </Grid>

以及检索style并应用它的代码隐藏方法:

private void TestSomeStuff()
    {
        var style = this.TryFindResource("SciChartSurfaceStyle") as Style;
        var sciChartSurface1 = new SciChartSurface() {Style = style};
        var panel1 = new LayoutPanel(){Content=sciChartSurface1};
        var style2 = this.TryFindResource("SciChartSurfaceStyle") as Style;
        var sciChartSurface2 = new SciChartSurface() {Style = style2};
        var panel2 = new LayoutPanel() {Content = sciChartSurface2};
        LayoutGroup.Add(panel1);
        LayoutGroup.Add(panel2);
    }

编辑

panel1添加到LayoutGroup工作得很好,但是一旦我尝试添加panel2,就会发生运行时错误。此外,只要不将style注入SciChartSurface的新实例中,它就可以正常工作。一旦我将样式注入两个新表面,就会弹出错误。

在代码隐藏中使用以 xaml 声明的自定义“样式”会引发运行时错误

不要直接在代码后面设置 Style:

var style = this.TryFindResource("SciChartSurfaceStyle") as Style;
var sciChartSurface1 = new SciChartSurface() {Style = style};

但是使用SetValue方法:

var style = this.TryFindResource("SciChartSurfaceStyle") as Style;
var sciChartSurface1 = new SciChartSurface();
sciChartSurface1.SetValue(StyleProperty, style);