ItemsControl 中的用户控件不会填充模拟属性

User control inside ItemsControl doesn't populate with mocked properties

提问人:Eric Eggers 提问时间:10/21/2023 最后编辑:Eric Eggers 更新时间:10/23/2023 访问量:61

问:

我正在制作一个演示应用程序,其中具有两个属性 Name 和 Color 的简单类 Fruit 显示在 FruitUC 中,每个属性都有一个字段。在 ProduceVM 类中,我用 Fruit 实例填充 ObservableCollection SupportedFruits,并将 ProduceVM 实例绑定到另一个用户控件 FruitView,其中 ItemsControl 显示 SupportedFruits 的每个元素。我还有一个 ProduceVM 的 MockProduceVM 子类,它创建向 SupportedFruits 添加 3 个 Fruit 对象,我应该能够在设计时看到这些对象。

在运行时一切正常,但在设计时 FruitUC 是空的。如果在 ItemsControl 中,我有显示每个水果的名称和颜色的文本框,它们就可以很好地模拟。但是,每个 FruitUC 都假定绑定到相同的数据,其行为就好像两个属性都是空白字符串一样。在 FruitView 的 ItemsControl 中缺少什么 FruitUC?提前致谢,对这种格式感到抱歉......

水果:

public class Fruit : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;

private string _name;
private string _color;

public string Name {
  get { return _name; }
  set {
    if (_name != value) {
      _name = value;
      NotifyListeners();
    }
  }
}

public string Color {
  get { return _color; }
  set {
    if (_color != value) {
      _color = value;
      NotifyListeners();
    }
  }
}

private void NotifyListeners([CallerMemberName] string propertyName = "") {
  try {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  } catch (Exception anException) {
    throw anException;
  }
}

FruitUC.xaml:

<UserControl x:Class="WPFInAction.FruitUC"
         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:WPFInAction"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
<Grid Background="LightGray" d:DataContext="{d:DesignInstance Type=local:Fruit, IsDesignTimeCreatable=True}">
    <Grid.Resources>
        <Style TargetType="TextBlock">
            <Setter Property="FontSize" Value="20" />
            <Setter Property="HorizontalAlignment" Value="Right" />
            <Setter Property="Margin" Value="5,1,5,0" />
        </Style>
        <Style TargetType="TextBox">
            <Setter Property="MinWidth" Value="80" />
            <Setter Property="Height" Value="30" />
            <Setter Property="FontSize" Value="20" />
        </Style>
    </Grid.Resources>
    <Grid.RowDefinitions>
        <RowDefinition Height="10" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <TextBlock x:Name="lblFruitName" Text="Name:" Grid.Row="1" />
    <TextBox x:Name="txtFruitName" Text="{Binding Name}" Grid.Row="1" Grid.Column="1" />
    <TextBlock x:Name="lblFruitColor" Text="Color:" Grid.Row="2" />
    <TextBox x:Name="txtFruitColor" Text="{Binding Color}" Grid.Row="2" Grid.Column="1" />
</Grid>

FruitUC.xaml.cs:

public partial class FruitUC : UserControl {

public FruitUC() {
  InitializeComponent();
}
}

生产虚拟机:

public class ProduceVM {
public ObservableCollection<Fruit> SupportedFruits { get; set; }

public ProduceVM() {
  SupportedFruits = new ObservableCollection<Fruit>();
    private static readonly string[] _fruitNames = { "Apple", "Orange", "Banana", "Avocado", "Blueberry", "Grape" };
private static readonly string[] _fruitColors = { "Red", "Orange", "Yellow", "Green", "Blue", "Purple" };

  if (!DesignerProperties.GetIsInDesignMode(new System.Windows.DependencyObject())) {
    for (var f = 0; f < _fruitNames.Length; f++) {
      SupportedFruits.Add(new Fruit { Name = _fruitNames[f], Color = _fruitColors[f] });
    }
  }
}

}

MockProduceVM:

public class MockProduceVM : ProduceVM {
public MockProduceVM() : base() {
  SupportedFruits.Add(new Fruit { Name ="Grape", Color = "Red" });
  SupportedFruits.Add(new Fruit { Name ="Apple", Color = "Yellow" });
  SupportedFruits.Add(new Fruit { Name ="Banana", Color = "Green" });
}
}

FruitsView.xaml:

<UserControl x:Class="WPFInAction.FruitsView"
         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:WPFInAction"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
<DockPanel d:DataContext="{d:DesignInstance Type=local:MockProduceVM, IsDesignTimeCreatable=True}" Background="AliceBlue">
    <ItemsControl ItemsSource="{Binding SupportedFruits}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Vertical"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <WrapPanel Orientation="Vertical">
                    <local:FruitUC />
                    <TextBox x:Name="txtFruitName" Text="{Binding Name}" Width="70" />
                    <TextBox x:Name="txtFruitColor" Text="{Binding Color}" Width="70" Margin="10,0,0,10" />
                </WrapPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</DockPanel>

FruitsView.xaml.cs:

  public partial class FruitsView : UserControl {
public FruitsView() {
  InitializeComponent();
  DataContext = new ProduceVM();
}
}

在运行时:enter image description here

在设计/模拟时:

enter image description here

编辑:我注意到,如果我对 MockProduceVM 进行更改,然后构建,然后转到 FruitsView.xaml,我会看到属性值已设置,然后在一瞬间它们清空。

编辑2:如果我用FruitUC的内容替换FruitsView中的FruitUC,则“名称”和“颜色”字段仍然显示为空白。

C# WPF 模拟 用户控件 ItemsControl

评论

0赞 Clemens 10/21/2023
UserControl 不得设置自己的 DataContext。它防止从 ItemsControl 中的项容器继承 DataContext。
0赞 Eric Eggers 10/21/2023
我注释掉了 DataContext = new ProduceVM();行.cs但这仍然会发生。

答:

2赞 LittleBit 10/23/2023 #1

在你覆盖了 for the desgin-timeFreuitUC.xamlDatacontextGrid

<Grid Background="LightGray" d:DataContext="{d:DesignInstance Type=local:Fruit, IsDesignTimeCreatable=True}">

所以在里面,它不再在集合的集合项上。GridDataContextSupportedFruits

删除覆盖,应该没问题。DataContext

enter image description here

评论

1赞 Eric Eggers 10/23/2023
确实如此!非常感谢,享受赏金!(当他们让我在 22 小时内授予它时)
0赞 ASh 10/24/2023
“删除 DataContext 覆盖” - d:DataContext 在 UserControl 上设置,而不是在 Grid 上设置应该有效,不是吗?
0赞 Eric Eggers 10/25/2023
@ASh 这没什么区别。