自定义UserControl与ContentControl字段

本文关键字:字段 ContentControl UserControl 自定义 | 更新日期: 2023-09-27 18:05:33

我有一个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>
到列表的数据绑定发生了,但是控件中没有显示任何内容。我猜它还在那里,但太小了,看不见(未定义的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");}
        }
    }

自定义UserControl与ContentControl字段

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

你似乎想要绑定到UserControl的属性,但你直接绑定到DataContext的属性,这是你的ViewModel,因此在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>

去掉那些依赖属性改变的回调函数,并将ViewModels中的属性代码更改为以下格式,以确保它已更改:

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