我有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");}
}
}
答案 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");
}
}
}