【问题标题】:Modify Grid of a UserControl in MainPage.xaml在 MainPage.xaml 中修改 UserControl 的网格
【发布时间】:2014-04-11 09:21:55
【问题描述】:

我发现了很多关于这个主题的帖子,但我的应用程序无法运行,所以我在这里提出一个新问题。

我想制作一个用户控件元素,它有一个可以从外部填充的网格。 这是 UserControl-Xaml-Part:

<Grid>
    <Grid.ColumnDefinitions>
         <ColumnDefinition Width="70"/>
         <ColumnDefinition Width="*"/>
         <ColumnDefinition Width="Auto"/>
         <ColumnDefinition Width="*"/>
         <ColumnDefinition Width="70"/>
     </Grid.ColumnDefinitions>

     <Grid Grid.Column="2" x:Name="ButtonGrid"/>
</Grid>

在我的 MainPage.xaml 之外,我想像这样使用它:

<UserControls:MyControl>
    <UserControls:MyControl.ButtonGrid>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="130"/>
                <ColumnDefinition Width="130"/>
                <ColumnDefinition Width="130"/>
                <ColumnDefinition Width="130"/>
            </Grid.ColumnDefinitions>
            // Add elements and stuff
        </Grid>
    </UserControls:MyControl.ButtonGrid>
</UserControls:AppBar>

但我还没有走到这一步。它说“ButtonGrid”未被识别或无法访问成员(我的德语错误消息翻译)。但是当我输入UserControls:MyControl. 时,它会提示ButtonGrid

MyControl.xaml.cs 如下所示:

namespace myApp
{
    public partial class MyControl: UserControl
    {
        public Grid ButtonGrid { get; set; }

        // or
        public Grid ButtonGrid
        {
            get { return (Grid)GetValue(ButtonGridProperty); }
            set { SetValue(ButtonGridProperty, value); }
        }
        public static readonly DependencyProperty ButtonGridProperty =
            DependencyProperty.Register("ButtonGrid", typeof(Grid), typeof(MyControl), new PropertyMetadata(new Grid()));

        public MyControl()
        {
            InitializeComponent();
        }
    }
}

我尝试了许多方法来使这个“ButtonGrid”值可见并起作用,但仍然没有。有什么想法吗?

编辑 我可以使用简单的 getter 在代码隐藏中获取 Grid。但是,在某个地方创造东西然后把它们放到我想要的地方并不是直接的。

【问题讨论】:

    标签: c# xaml windows-phone-8 user-controls


    【解决方案1】:

    在 XAML 中为元素设置名称会为该对象创建一个私有字段,然后您可以在代码隐藏中访问该字段。当您尝试使用它时,它不会使其成为其他内容的占位符。如果您想将外部内容注入您的 XAML,请使用 ContentPresenter 或一些 ContentControl 派生类,并将您要注入的内容设置为其 Content 属性。这是ContentControls 通常使用的模式,因此您可以查看Button 的默认模板并查看此模式。

    所以要使用这个:

    <local:MyControl>
      <local:MyControl.CustomContent>
        <Grid>
          <!-- elements and stuff to pass in -->
        </Grid>
      </local:MyControl.CustomContent>
    </local:MyControl>
    

    您将在 MyControl (CustomContent) 中拥有一个 DependencyProperty,就像您已经尝试过的那样(但它应该是类型对象,除非您对其他类型有特定原因)。然后你的控件的 XAML 看起来更像:

    <Grid>
      <Grid.ColumnDefinitions>
        ...
      </Grid.ColumnDefinitions>
    
      <ContentPresenter Grid.Column="2" Content="{Binding CustomContent, RelativeSource={RelativeSource FindAncestor, AncestorType=local:MyControl}}"/>
    </Grid>
    

    【讨论】:

    • 感谢您的回答!这不正是我想要的。我想将 UserControl 用作“标准设计”并在普通 .xaml 中定义内部“元素和东西”。我将尝试反转您的建议并使用 UserControl 中的 ContentPresenter。
    • 好的,我明白我误解了.. 现在尝试实施。当它工作或我放弃时会再次发布:D
    • 现在我试了一下。遗憾的是,Windows Phone 不支持 AncestorType。 (stackoverflow.com/questions/15233072/…)。我还不确定FindAncestor。尝试寻找WP8方式
    【解决方案2】:

    感谢 John Bowen 的正确想法。现在我到目前为止最好的解决方案是: MainPage.xaml

    <local:MyControlx:Name="Control" Grid.Row="1" Grid.RowSpan="2"
                                    Height="98" VerticalAlignment="Bottom">
        <local:MyControl.Content>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="130"/>
                    <ColumnDefinition Width="130"/>
                    <ColumnDefinition Width="130"/>
                    <ColumnDefinition Width="130"/>
                </Grid.ColumnDefinitions>
    
            <!-- Stuff inside that works! -->
    
            </Grid>
        </local:MyControl.Content>
    </local:MyControl>
    

    还有 MyControl.xaml(现在是 ContentControl!):

    <Grid x:Name="MyCtrl" Background="{StaticResource PhoneAccentBrush}"
          Height="98" VerticalAlignment="Bottom"
          Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=ActualWidth}">
        <Grid.RenderTransform>
            <TranslateTransform x:Name="moveTransform" />
        </Grid.RenderTransform>
    
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="70"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
           <ColumnDefinition Width="70"/>
        </Grid.ColumnDefinitions>
    
        <ContentPresenter Grid.Column="2"
                          Content="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataContext}"/>
    
        <!-- Buttons and stuff that should be always there in Grid.Column=0 and Grid.Column=4 -->
    
        </Button>
    </Grid>
    

    MainPage.xaml 中的按钮和内容是可见的、可点击的,并且没有任何崩溃。但我看不到 MyControl.xaml 内部的按钮或 PhoneAccentBrush-background =/ 所以这一定是我错过了什么的正确方式..

    编辑: 如果我将 MyControl 设置为 UserControl,.Content 会覆盖里面的所有内容。 如果我将其设为 ContentControl,它似乎会看到内部 Grid,因为它将所有内容几乎都放在了正确的位置。但是我仍然看不到在 MyControl 中声明的任何其他元素。如果我不设置 .Content 我会看到所有内部的东西,所有的方法都在工作,但当然没有我想放在里面的东西。

    编辑2: 我以某种方式管理它,但偶然发现了新的错误。但我想最好链接另一个线程;) Keep a reference to objects passed to a UserControl

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 2018-10-18
      • 1970-01-01
      • 2019-06-19
      • 2012-11-14
      • 2013-08-04
      相关资源
      最近更新 更多