none
子控件如何自动适应父控件的宽度 RRS feed

  • 问题

  • 我想实现根据数据类型自动选择数据末班的效果:

    <ItemsControl ItemsSource="{Binding ZxList}">

                        <ItemsControl.ItemTemplate>

                            <DataTemplate>

                                <DataTemplateSelector Content="{Binding .}" />

                            </DataTemplate>

                        </ItemsControl.ItemTemplate>

                    </ItemsControl>

    DataTemplateSelector  类如下:

    public class DataTemplateSelector : ContentControl

        {

            protected override void OnContentChanged(object oldContent, object newContent)

            {

                ContentTemplate = this.FindResource<DataTemplate>(newContent.GetType().FullName);

            }

        }

    实现是可以了,但是 现在需要 DataTemplate 中的空间 跟ItemsControl一样大(我的ItemsControl是放在 Gril里面的)。

    如果不用DataTemplateSelector  而直接使用 指定的 DataTemplate是可以的。

    怀疑是 DataTemplateSelector  继承自 ContentControl 造成的。

    这个应该怎么解决?

    或者 有没什么属性或者其他办法 让子控件 能自动适应父控件的大小?

    2011年3月18日 8:20

答案

全部回复

  • 如果你能提供你的需求,现在实现的状态,详细一点的Xaml 信息,我想我能给你提供更好的解决方案。

    现在,我只能根据我的经验 还有你最终最关心的问题 去给你提供解决方案。

    -->  , 有没什么属性或者其他办法 让子控件 能自动适应父控件的大小?

    给你一个万能的方法,那就是将你的子控件的宽度和父控件的宽度进行绑定,

    比如子控件是A, 父控件是B。你就可以这样写你的代码:

    <A Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType= B}, Path=ActualWidth}" />

    然后你将宽度类似上面的方法 也进行绑定,就能实现你的效果了。

     

    Best regards,

     

     


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年3月18日 12:47
    版主
  • 谢谢 Sheldon_Xiao:

     我做的是Windows phone 7上面的开发。

     我的具体需求是:在我们的需求中,有资讯栏目和资讯标题,且都想让他们用列表的方式来展现。栏目和标题分别定义为:InfoDetailViewModel 和 HSColumnViewModel,想用一个ItemsControl(本来想直接用ListBox,遇到的问题后面再详述)可以让这两种类型的数据都可以通过列表的方式来展示。

            WPF的DataTemplate有个 DataType属性,不过在Windows phone 7中没有,不过在网上找到上面提到的那种方法来做同样的事情,我的Xaml文件如下:

     

     

    <Grid>

     

                <ScrollViewer Grid.Row="4"  VerticalScrollBarVisibility="Auto">

                    <ItemsControl x:Name="ZxListBox" ItemsSource="{Binding ZxList}">

                        <ItemsControl.ItemTemplate>

                            <DataTemplate>

                                <HSModelBase:DataTemplateSelector Content="{Binding .}" />

                            </DataTemplate>

                        </ItemsControl.ItemTemplate>

                    </ItemsControl>

                </ScrollViewer>

     

            </Grid>

    ZxList 的类型可能为 ObservableCollection<InfoDetailViewModel>  和 ObservableCollection<HSColumnViewModel>.

    DataTemplateSelector 的定义仍然跟前面的一样:

     

    public class DataTemplateSelector : ContentControl

        {

            protected override void OnContentChanged(object oldContent, object newContent)

            {

                ContentTemplate = this.FindResource<DataTemplate>(newContent.GetType().FullName);

            }

        }

    FindResource<T>方法如下:

     

    public static T FindResource<T>(this DependencyObject initial, string key)

            {

                DependencyObject current = initial;


                while (current != null)

                {

                    if (current is FrameworkElement)

                    {

                        if ((current as FrameworkElement).Resources.Contains(key))

                        {

                            return (T)(current as FrameworkElement).Resources[key];

                        }

                    }


                    current = VisualTreeHelper.GetParent(current);

                }


                if (Application.Current.Resources.Contains(key))

                {

                    return (T)Application.Current.Resources[key];

                }

                return default(T);

            }

    (这两个方法的定义都是从网上一个朋友那里拷贝来的,希望别有侵权哈)

    下面是两个对应的DataTemplate:

     

    <DataTemplate x:Key="HSWinner.ViewModel.HSInfoDetailViewModel">

                <Grid>

                    <Grid.ColumnDefinitions>

                        <ColumnDefinition Width="Auto"/>

                        <ColumnDefinition Width="*"/>

                    </Grid.ColumnDefinitions>

                    <Grid.RowDefinitions>

                        <RowDefinition Height="Auto"/>

                        <RowDefinition Height="Auto"/>

                    </Grid.RowDefinitions>

                    <Image Source="{StaticResource Info_li_img}" Margin="15 15 15 15" VerticalAlignment="Center" Grid.Column="0"/>

                    <StackPanel Grid.Column="1" UseLayoutRounding="False">

                        <StackPanel Orientation="Horizontal">

                            <TextBlock  Text="{Binding Title}" FontSize="28"/>

                            <Image Source="{Binding ZxState, Converter={StaticResource InfoStateToImg}}" HorizontalAlignment="Right"/>

                        </StackPanel>

                        <TextBlock Text="{Binding Date}" HorizontalAlignment="Right" FontSize="28"/>

                    </StackPanel>

                    <Rectangle Height="2" Fill="Red" Grid.Row="1" Grid.ColumnSpan="2"/>

                </Grid>

            </DataTemplate>

            <DataTemplate x:Key="HSWinner.ViewModel.HSColumnInfoViewModel">

                <StackPanel Orientation="Horizontal" Margin="7 6 8 5">

                    <Image Source="{StaticResource Info_Root_Normal}" Stretch="None" VerticalAlignment="Center" Grid.Column="0"/>

                    <TextBlock Text="{Binding Name}" FontSize="28" Foreground="Blue" VerticalAlignment="Center" />

                </StackPanel>

            </DataTemplate>

    现在得到的结果:

     

    图片不知道能不能看到!
    如果去掉:

    <ItemsControl.ItemTemplate>

                            <DataTemplate>

                                <HSModelBase:DataTemplateSelector Content="{Binding .}" />

                            </DataTemplate>

                        </ItemsControl.ItemTemplate>

    而直接用 <ItemsControl x:Name="ZxListBox" ItemsSource="{Binding ZxList}" ItemTemplate="{StaticResource HSWinner.ViewModel.HSInfoDetailViewModel}“>

    那么结果是这样的:

    所以我怀疑是 DataTemplateSelector 因为是继承自 ContentControl 造成的。
    请问有什么好的办法没?
    不好意思 我试了一下 好像 Windows phone 7 中 RelativeSource 不支持 AncestorType呢。
    前面我本来想用 ListBox来做列表的。但是同样是出现这个问题,ListBoxItem的大小不会跟ListBox的大小一样大儿子自己缩成一团,如下:
    请问 有什么好的解决办法没? 写了这么多不知道表述清楚了没,谢谢 Sheldon_Xiao。试了下 图片出不来咋办?

     


    2011年3月21日 3:13
  • 水平对齐方式设置为拉伸即可!
    2011年3月22日 1:36
  • 是水平的Content设置为拉伸,比如:

    <ListBox HorizontalContentAlignment="Stretch"/>

     如果你的问题依然存在,我建议你到 “Windows Phone用户” 这个论坛提问,链接是:

    http://social.microsoft.com/Forums/zh-CN/windowsmobilezhchs/threads

    因为 Windows Phone 7是不支持WPF,而是SilverLight的。 

     


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    • 已标记为答案 ylhhunter 2011年3月22日 5:44
    2011年3月22日 3:51
    版主
  • 试了下 可以用,谢谢。
    2011年3月22日 5:53