ObservableCollection 中的绑定用户控件未显示在uniformgrid 中

AEv*_*ers 1 c# wpf xaml mvvm

因此,我对 C#/XAML 相当陌生,并且一直在尝试通过重写旧项目来自学 MVVM。我遇到了一个问题,应该将用户控件添加到统一网格中。如果我自己实现用户控件,它会显示得很好,但如果我将其添加到 ObservableCollection,然后尝试将其绑定到uniformgrid,则会显示用户控件的路径,而不是实际的 UI 元素。不幸的是,我对 C# 和 MVVM 还很陌生,无法确定具体是什么问题,这使得在线搜索变得困难。

<UserControl x:Class="CMS.Views.MonthView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:CMS.Views"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
    <ItemsControl ItemsSource="{Binding Dates}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid IsItemsHost="True" Columns="7"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
    </Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

月视图.cs

namespace CMS.Views
{
    public partial class MonthView : UserControl
    {
        public MonthView()
        {
            InitializeComponent();
            MonthViewModel monthViewModelObject = MonthViewModel.GetMonthViewModel();
            this.DataContext = monthViewModelObject;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

月视图模型

namespace CMS.ViewModels
{
    class MonthViewModel
    {
        private readonly ObservableCollection<DayViewModel> _dates = new ObservableCollection<DayViewModel>();

        public IReadOnlyCollection<DayViewModel> Dates
        {
            get { return _dates; }
        }

        public static MonthViewModel GetMonthViewModel()
        {
            var month = new MonthViewModel();
            month.testdaymodel();
            return month;
        }

        public void testdaymodel()
        {
            DayViewModel DVM = DayViewModel.GetDayViewModel();
            DVM.LoadDate(DateTime.Now);
            _dates.Add(DVM);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

DayView 的 XAML 具有 DataTemplate

<UserControl x:Class="CMS.Views.DayView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:local="clr-namespace:CMS.Views" 
    mc:Ignorable = "d"
    MinWidth="100" MinHeight="100" BorderBrush="LightSlateGray" BorderThickness="0.5,0.5,1.5,1.5">

    <UserControl.Resources>
        <ResourceDictionary>
        </ResourceDictionary>
    </UserControl.Resources>

    <DataTemplate x:Name ="DayBox">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="21"/>
                <RowDefinition  Height="*"/>
            </Grid.RowDefinitions>
            <Border x:Name="DayLabelRowBorder" CornerRadius="2" Grid.Row="0" BorderBrush="{x:Null}" Background="{DynamicResource BlueGradientBrush}">
                <Label x:Name="DayLabel" Content="{Binding Path = Info.Day, Mode = OneWay}" FontWeight="Bold" FontFamily="Arial"/>
            </Border>

            <!--This will be bound to the event schedule for a given day-->
            <StackPanel Grid.Row="1" x:Name="DayAppointmentsStack" HorizontalAlignment="Stretch" Background="White" VerticalAlignment="Stretch">
            </StackPanel>
        </Grid>
    </DataTemplate>
</UserControl>
Run Code Online (Sandbox Code Playgroud)

jan*_*mus 5

编辑:无论您使用的是简单控件(如 a)Label还是您自己的控件(如 ),都适用相同的规则DayView

您需要设置ItemsControl.ItemTemplate将绑定到您的IReadOnlyCollection<DayViewModel>.

然后,做一个DataTemplate你喜欢的。像这样:

<ItemsControl ItemsSource="{Binding Dates}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid IsItemsHost="True" Columns="7"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <!-- This control is automatically bound to each DayViewModel instance -->
            <local:DayView />
            <!-- 
            <Label Content="{Binding PropertyToDisplay}" ></Label>
            -->
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)

您没有显示该类DayViewModel,因此您只需将 更改PropertyToDisplay为您希望视图显示的实际属性。

编辑:制作将自动将其绑定到DayView中的项目。ItemsControl.TemplatetypeItemSource

这意味着您可以将DayView其视为UserControlwith ,而无需显式设置DayViewModelDataContext

我假设View你的实际DayView是在Grid里面DataTemplate,所以我只是修改了代码如下:

DayView.xaml

<UserControl x:Class="CMS.Views.DayView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:local="clr-namespace:CMS.Views" 
    mc:Ignorable = "d"
    MinWidth="100" MinHeight="100" BorderBrush="LightSlateGray" BorderThickness="0.5,0.5,1.5,1.5">

    <UserControl.Resources>
        <ResourceDictionary>
        </ResourceDictionary>
    </UserControl.Resources>

    <!-- <DataTemplate x:Name ="DayBox"> -->

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="21"/>
                <RowDefinition  Height="*"/>
            </Grid.RowDefinitions>
            <Border x:Name="DayLabelRowBorder" CornerRadius="2" Grid.Row="0" BorderBrush="{x:Null}" Background="{DynamicResource BlueGradientBrush}">
                <Label x:Name="DayLabel" Content="{Binding Path = Info.Day, Mode = OneWay}" FontWeight="Bold" FontFamily="Arial"/>
            </Border>

            <!--This will be bound to the event schedule for a given day-->
            <StackPanel Grid.Row="1" x:Name="DayAppointmentsStack" HorizontalAlignment="Stretch" Background="White" VerticalAlignment="Stretch">
            </StackPanel>
        </Grid>

    <!-- </DataTemplate> -->

</UserControl>
Run Code Online (Sandbox Code Playgroud)