简体   繁体   English

如何在Windows Phone 8中访问UserControl的组件/元素

[英]How to access Components/Elements of UserControl in Windows Phone 8

I had developed UserControl for my windows phone 8 which is as follows. 我为Windows Phone 8开发了UserControl,如下所示。

<UserControl x:Class="SpinrWindowsMobile.UserControls.ProgressiveLongListSelector"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    d:DesignHeight="480" d:DesignWidth="480">

    <Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="Auto"></RowDefinition>
        </Grid.RowDefinitions>
        <phone:LongListSelector Grid.Row="0"  Name="longlistselector">
        </phone:LongListSelector>
        <StackPanel Grid.Row="1">
            <ProgressBar Name="listProress" IsIndeterminate="True"></ProgressBar>
            <TextBlock Name="ProgressText" Text="Loading..."></TextBlock>
        </StackPanel>
    </Grid>
</UserControl>

As you can see in above xaml I had used LongListSelector and the StackPanel inside Grid Control. 如您在上面的xaml中所见,我在Grid Control中使用了LongListSelector和StackPanel I am using this control in my MainPage.xaml which is as follows. 我在MainPage.xaml中使用此控件,如下所示。

<phone:PhoneApplicationPage
    x:Class="SpinrWindowsMobile.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:UserControls="clr-namespace:SpinrWindowsMobile.UserControls"
    mc:Ignorable="d"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">
    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">     
            <UserControls:ProgressiveLongListSelector>

            </UserControls:ProgressiveLongListSelector>

     </Grid>    
</phone:PhoneApplicationPage>

Upto this it is fine but I want to do something which is as follows. 到目前为止,这很好,但是我想做如下的事情。

  <UserControls:ProgressiveLongListSelector>
                  <UserControls:ProgressiveLongListSelector.longlistselector 
                 ItemsSource="Binding" ItemTemplate="{staticresource myTemplate}">
                  </UserControls:ProgressiveLongListSelector.longlistselector>
    </UserControls:ProgressiveLongListSelector>

How Can I access the longlistselector which is an element/component of UserControl ? 如何访问longListselector,它是 UserControl 的元素/组件 Benefit of this is I can directly set the LongListSelector Properties in the xaml(in which i am embedding My usercontrol) itself . 这样做的好处是, I can directly set the LongListSelector Properties in the xaml(in which i am embedding My usercontrol) itself For me this kind of stuff is day today requirement. 对我来说,这种东西是今天的必需品。

can anyone guide me how to do this? 谁能指导我该怎么做?

Since you are extending and modifying LongListSelector, I would recommend subclassing and retemplating LongListSelector instead of placing it inside a UserControl. 由于您正在扩展和修改LongListSelector,因此我建议对LongListSelector进行子类化和重新模板化,而不是将其放置在UserControl中。 That will allow you to access all the existing properties and methods on LongListSelector, and use your new ProgressiveLongListSelector exactly like you would a LongListSelector. 这将允许您访问LongListSelector上的所有现有属性和方法,并像使用LongListSelector一样完全使用新的ProgressiveLongListSelector。

To start, you can create a new class that subclasses LongListSelector: 首先,您可以创建一个新类,该类将LongListSelector子类化:

public class ProgressiveLongListSelector : LongListSelector {

    public ProgressiveLongListSelector() {
        DefaultStyleKey = typeof(ProgressiveLongListSelector);
    }
}

Note the DefaultStyleKey . 注意DefaultStyleKey That's where the new control template will come from. 这就是新控件模板的来源。

Now you can place the following style in your App.xaml resources. 现在,您可以在App.xaml资源中放置以下样式。 Note that the TargetType is ProgressiveLongListSelector . 注意, TargetTypeProgressiveLongListSelector This is how DefaultStyleKey will find your new default style. 这是DefaultStyleKey将如何找到新的默认样式的方式。

    <Style TargetType="phoneApp2:ProgressiveLongListSelector">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="phoneApp2:ProgressiveLongListSelector">
                    <Grid Background="{TemplateBinding Background}" d:DesignWidth="480" d:DesignHeight="800">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="ScrollStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition GeneratedDuration="00:00:00.5" />
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="Scrolling">
                                    <Storyboard>
                                        <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="VerticalScrollBar" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="NotScrolling" />
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid Margin="{TemplateBinding Padding}">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="auto" />
                            </Grid.ColumnDefinitions>
                            <ViewportControl x:Name="ViewportControl" HorizontalContentAlignment="Stretch" VerticalAlignment="Top" />
                            <ScrollBar x:Name="VerticalScrollBar" Grid.Column="1" Margin="4,0,4,0" Opacity="0" Orientation="Vertical" />
                        </Grid>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

This style / template is a copy of the default LongListSelector template (extracted from Blend). 此样式/模板是默认LongListSelector模板的副本(从Blend中提取)。 From here, you can add the other elements in your UserControl, such as the ProgressBar and TextBlock, to the template. 从这里,您可以将UserControl中的其他元素(例如ProgressBar和TextBlock)添加到模板。

What you could do is to expose properties of your UserContorl using DependencyProperty mechanism. 您可以做的是使用DependencyProperty机制公开UserContorl的属性。 Then you can set them in XAML, from the Page's which are using that UserControl. 然后,您可以在使用该UserControl的Page的XAML中进行设置。 I'm not sure if you want to expose all the bits of your VisualTree, since this could change in future. 我不确定是否要公开VisualTree的所有位,因为将来可能会改变。 But you can expose some properties which affect your UserControl's behavior indirectly. 但是,您可以公开一些会间接影响UserControl行为的属性。

Here's an example how this can be done: 这是一个如何完成此操作的示例:

(this example is taken from my code, but I guess you can figure out how to adapt it) (此示例摘自我的代码,但我想您可以弄清楚如何对其进行调整)

First you declare a DependencyProperty in your UserControl: 首先,您在UserControl中声明一个DependencyProperty:

public partial class MyUserControl : UserControl
{
    public bool IsEditingMode
    {
        get { return (bool)GetValue(IsEditingModeProperty); }
        set { SetValue(IsEditingModeProperty, value); }
    }

    public static readonly DependencyProperty IsEditingModeProperty =
        DependencyProperty.Register("IsEditingMode", typeof(bool), typeof(MyUserControl), new PropertyMetadata(false, IsEditingModeChanged));
}

private static void IsEditingModeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    // this will be called when someone would set the exposed property to some new value
}

Next you add MyUserControl to some Page and set that property: 接下来,将MyUserControl添加到某些Page并设置该属性:

<phone:PivotItem Header="{Binding Path=LocalizedResources.MyPivotHeader, Source={StaticResource LocalizedStrings}}" Margin="0">
    <my:MyUserControl x:Name="People" IsEditingMode="True"/>
</phone:PivotItem>

Notice how IsEditingMode is set in XAML. 注意如何在XAML中设置IsEditingMode Of course, you could also set it from the code, using the public bool IsEditingMode property wrapper around the IsEditingModeProperty . 当然,您也可以使用public bool IsEditingMode周围的public bool IsEditingMode属性包装器从代码中进行IsEditingModeProperty

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM