Silverlight:将datacontext应用于样式中的元素

时间:2022-11-05 11:52:27

I have defined a style in app.xaml. This style contains several text TextBlocks which I would like to controle as I apply the style to an object, in this case a UserPin. How can I access these TextBlocks runtime? I get the style by:

我在app.xaml中定义了一个样式。这个样式包含几个文本TextBlocks,我想控制一个对象,在这种情况下是一个UserPin。如何访问这些TextBlocks运行时?我得到的风格是:

Style = Application.Current.Resources["UserPin"] as Style;

The style looks like this:

风格如下:

<Style x:Name="UserPin" TargetType="RRML_UserControls:UserPin" >
    <Setter Property="RenderTransformOrigin" Value="0.5,0.5" />
    <Setter Property="AnchorPoint" Value="0.5,0.5" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="RRML_UserControls:UserPin">
                <Grid Height="71.969" Width="Auto">
                    <Grid.RenderTransform>
                        <ScaleTransform x:Name="PART_PinScale" />
                    </Grid.RenderTransform>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="29"/>
                        <RowDefinition Height="16"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="0.247*"/>
                        <ColumnDefinition Width="20"/>
                        <ColumnDefinition Width="0.753*"/>
                    </Grid.ColumnDefinitions>
                    <Image Height="Auto" Source="Resources/Users.png" x:Name="PART_imgUser" VerticalAlignment="Top" Stretch="Uniform" Margin="0,0,0,0" Grid.Column="1">
                        <Image.RenderTransform>
                            <TransformGroup>
                                <ScaleTransform/>
                                <SkewTransform/>
                                <RotateTransform/>
                                <TranslateTransform/>
                            </TransformGroup>
                        </Image.RenderTransform>
                    </Image>
                    <TextBlock HorizontalAlignment="Center" Margin="0,0,0,0" Width="Auto" Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" TextWrapping="Wrap" VerticalAlignment="Center" TextAlignment="Center" x:Name="txtBottom" Text="{Binding Mode=OneWay, Path=LocationName}">
                        <TextBlock.DataContext>
                            <RRML_RRMLServiceReference:Location LocationName="Initial Name"/>
                        </TextBlock.DataContext>
                    </TextBlock>                            
                    <TextBlock HorizontalAlignment="Right" Margin="0,0,0,0" VerticalAlignment="Center" Text="L" TextWrapping="Wrap"/>
                    <TextBlock Margin="0,0,0,0" Text="R" TextWrapping="Wrap" d:LayoutOverrides="Width, Height" Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Center"/>                            
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

The TextBlock value I'm trying to set is txtBottom. As you can see I have tried to apply a datacontext and a databinding to the field. This works, but all objects get the value "Initial Name" of course.

我试图设置的TextBlock值是txtBottom。如您所见,我已尝试将datacontext和数据绑定应用于该字段。这样可行,但所有对象当然都会获得值“初始名称”。

My questions are:

我的问题是:

  1. how can I apply my datacontext so txtBottom.Text changes, or
  2. 如何应用我的datacontext以便txtBottom.Text更改,或

  3. how can I change the value of the TextBlock named txtBottom without databinding?
  4. 如何在不进行数据绑定的情况下更改名为txtBottom的TextBlock的值?

  5. in short can I access these fields or properties at all?
  6. 总之,我可以访问这些字段或属性吗?

Runtime :) So far I have found that Triggers may be used only in WPF.

运行时:)到目前为止,我发现触发器只能在WPF中使用。

I think of something like this:

我想到这样的事情:

var styledobject = new NiceObject();
styledobject.Style = Application.Current.Resources["UserPin"] as Style;
styledobject.DataContext = locationData;

Where locationData is my object containing data.

其中locationData是包含数据的对象。

If anyone wonders; I am placing icons on a map and want to name them.

如果有人想知道;我在地图上放置图标并想要命名它们。

1 个解决方案

#1


  1. You should not explicitly apply DataContext on the TextBlock. DataContext is inherited by child FrameworkElements. You should try to set data context explicitly as little and as high up the Visual Tree as possible (for your own sanity's sake :-))

    您不应该在TextBlock上显式应用DataContext。 DataContext由子FrameworkElements继承。你应该尝试尽可能地将数据上下文设置为尽可能少的视觉树(为了你自己的理智:-))

  2. If this is a custom control, you can override on the OnApplyTemplate method and use the GetTemplateChild(string name) to retrieve references to named elements within your control.

    如果这是一个自定义控件,您可以覆盖OnApplyTemplate方法并使用GetTemplateChild(字符串名称)来检索对控件中命名元素的引用。

    public override void OnApplyTemplate() 
    {
            base.OnApplyTemplate();
    
    TextBlock txtBottom = GetTemplateChild("txtBottom") as TextBlock;
    }
    
  3. Externally, if you must, you can imperatively access that specific control at runtime using an extension method to traverse the Visual Tree to find it by name.

    在外部,如果必须,您可以使用扩展方法在运行时以命令方式访问该特定控件,以遍历Visual Tree以按名称查找它。

    public static T FindChild<T>(this DependencyObject element, string name)
                where T : FrameworkElement
    {
    //Code to find the control
    }
    

#1


  1. You should not explicitly apply DataContext on the TextBlock. DataContext is inherited by child FrameworkElements. You should try to set data context explicitly as little and as high up the Visual Tree as possible (for your own sanity's sake :-))

    您不应该在TextBlock上显式应用DataContext。 DataContext由子FrameworkElements继承。你应该尝试尽可能地将数据上下文设置为尽可能少的视觉树(为了你自己的理智:-))

  2. If this is a custom control, you can override on the OnApplyTemplate method and use the GetTemplateChild(string name) to retrieve references to named elements within your control.

    如果这是一个自定义控件,您可以覆盖OnApplyTemplate方法并使用GetTemplateChild(字符串名称)来检索对控件中命名元素的引用。

    public override void OnApplyTemplate() 
    {
            base.OnApplyTemplate();
    
    TextBlock txtBottom = GetTemplateChild("txtBottom") as TextBlock;
    }
    
  3. Externally, if you must, you can imperatively access that specific control at runtime using an extension method to traverse the Visual Tree to find it by name.

    在外部,如果必须,您可以使用扩展方法在运行时以命令方式访问该特定控件,以遍历Visual Tree以按名称查找它。

    public static T FindChild<T>(this DependencyObject element, string name)
                where T : FrameworkElement
    {
    //Code to find the control
    }