Пользовательский UserControl с полем ContentControl - PullRequest
0 голосов
/ 15 августа 2011

У меня есть 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>

Привязка данных к списку происходит, однако ничего не отображаетсяв контроле.Я предполагаю, что это все еще там, но слишком маленькое, чтобы видеть (неопределенное ч / б).

Есть ли что-то, что я делаю не так?Заголовок показывает нормально, поэтому элемент управления работает несколько.

Редактировать:

Вот код для 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 Ответ

2 голосов
/ 16 августа 2011

В дополнение к тому, что я сказал в моем комментарии, вы, кажется, связываете свой DataContext в декларации UserControl, что является плохой вещью и проблемой всего этого.

Похоже, что вы хотите связать со свойствами UserControl, но вы связываете непосредственно со свойствами DataContext, который является вашей ViewModel, следовательно, установка свойства Body для экземпляра в XAML ничего не делает, так как свойство обходится внутренним переплет.

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");
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...