使用ContentControl字段自定义UserControl

时间:2011-08-15 19:23:35

标签: c# wpf xaml windows-phone-7

我有UserControl作为ContentControl的包装,它只是ContentControl的标题。

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

<Grid Background="Green" Grid.Row="0">
    <TextBlock  Text="{Binding Header}" Style="{StaticResource HeaderStyle}" Margin="12, 10, 0, 10" />
</Grid>
    <ContentControl HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Content="{Binding Body}" Grid.Row="1"/>
</Grid>

这是我尝试使用控件的地方:

<gbl:ListHeader Grid.Row="1" Visibility="{Binding HasMovies, Converter={StaticResource VisibilityConverter}}"  Header="{Binding Path=LocalizedResources.movie_list_header, Source={StaticResource LocalizedStrings}}" >
                    <gbl:ListHeader.Body>
                        <ListBox  SelectionChanged="ListBoxContainerSelectionChanged" ItemsSource="{Binding Movies}" ItemContainerStyle="{StaticResource HeaderListBoxItemStyle}">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <gbl:MovieItemControl Header="{Binding MovieTitle}" Description="{Binding FormattedDescription}" Detail="{Binding FormattedDetail}" Opacity="{Binding IsSuppressed, Converter={StaticResource DimIfTrueConverter}}"/>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                    </gbl:ListHeader.Body>

发生列表的DataBinding,但控件中没有显示任何内容。我猜它仍然存在,但是太小而无法看到(未定义的h / w)。

有什么我做错了吗?标题显示正常,因此控件似乎有点工作。

编辑:

这是ListHeader的代码隐藏:

public partial class ListHeader : UserControl
    {
        private readonly ListHeaderData _data = new ListHeaderData();
        public ListHeader()
        {
            InitializeComponent();
            DataContext = _data;
        }

        public string Header
        {
            get { return (string)GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Header.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HeaderProperty =
            DependencyProperty.Register("Header", typeof(string), typeof(ListHeader), new PropertyMetadata("",HeaderPropertyChanged) );

        private static void HeaderPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var lh = d as ListHeader;
            if (lh != null)
                lh._data.Header = e.NewValue as string;
        }



        public object Body
        {
            get { return GetValue(BodyProperty); }
            set { SetValue(BodyProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Body.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty BodyProperty =
            DependencyProperty.Register("Body", typeof(object), typeof(ListHeader), new PropertyMetadata(null, BodyPropertyChanged));

        private static void BodyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var lh = d as ListHeader;
            if (lh != null)
                lh._data.Body = e.NewValue;
        }
    }
    public class ListHeaderData : ViewModelBase
    {
        public ListHeaderData()
        {
            if (IsInDesignMode)
            {
                Header = "Custom Header Goes Here";
                Body = new Grid() { Background = new SolidColorBrush(Colors.Yellow) };
            }
        }
        private string _header;
        public string Header
        {
            get { return _header; }
            set { _header = value; RaisePropertyChanged("Header"); }
        }

        private object _body;
        public object Body
        {
            get { return _body; }
            set { _body = value; RaisePropertyChanged("Body");}
        }
    }

1 个答案:

答案 0 :(得分:2)

除了我在评论中所说的,你似乎在UserControl声明中绑定了你的DataContext,这是一件坏事以及所有这些的问题。

您似乎想要绑定到UserControl的属性,但是您直接绑定到您的ViewModel的DataContext的属性,因此在XAML中的实例上设置Body属性不会执行任何操作,因为内部回避了该属性结合。

对于我所知道的所有绑定,

UserControls应该是这样的:

<UserControl Name="control" ...>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <Grid Background="Green" Grid.Row="0">
            <TextBlock  Text="{Binding Header, ElementName=control}" Style="{StaticResource HeaderStyle}" Margin="12, 10, 0, 10" />
        </Grid>
        <ContentControl HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Content="{Binding Body, ElementName=control}" Grid.Row="1"/>
    </Grid>

删除那些依赖属性更改的回调并将ViewModel中的属性代码更改为此格式以确保更改:

private int _MyProperty = 0;
public int MyProperty
{
    get { return _MyProperty; }
    set
    {
        if (_MyProperty != value)
        {
            _MyProperty = value;
            OnPropertyChanged("MyProperty");
        }
    }
}