繁体   English   中英

将用户控件元素绑定到 Model 属性

[英]Binding User control elements to Model properties

我正在尝试将UserControl绑定到某个 model,但没有成功。

我有这个ItemsControl

<ItemsControl x:Name="spPatientFiles" Grid.Row="2"
              ItemsSource="{Binding PatientFiles, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
   <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
         <StackPanel/>
      </ItemsPanelTemplate>
   </ItemsControl.ItemsPanel>
   <ItemsControl.ItemTemplate>
      <DataTemplate DataType="{x:Type uc:PatientFile}">
         <uc:PatientFile/>
      </DataTemplate>
   </ItemsControl.ItemTemplate>
   <ItemsControl.DataContext>
      <ViewModels:MainViewModel/>
   </ItemsControl.DataContext>
</ItemsControl>

它受约束

public class MainViewModel
{
    public ObservableCollection<PatientFile> PatientFiles { get; set; }

    public MainViewModel()
    {
        PatientFiles = new ObservableCollection<PatientFile>();

        if (!string.IsNullOrEmpty(Models.LocalSettings.SaveFolder) &&
            System.IO.Directory.Exists(Models.LocalSettings.SaveFolder))
        {
            var files = System.IO.Directory.GetFiles(Models.LocalSettings.SaveFolder);

            foreach (var p in files)
            {
                var n = p.Substring(p.LastIndexOf("\\") + 1, p.LastIndexOf(".") - p.LastIndexOf("\\") - 1);
                var ext = p.Substring(p.LastIndexOf(".") + 1);

                PatientFiles.Add(new PatientFile()
                {
                    FileName = n,
                    Path = p,
                    FileType = ext == "avi" ? OutputType.Video : OutputType.Image
                });
            }
        }
    }
}

主要 xaml 有视图 Model:

<Window ...
        xmlns:ViewModels="clr-namespace:Octopus.Capturing.ViewModels"x:Class="Octopus.Capturing.Views.MainApp"
        ...>

这是我的UserControl ( uc:PatientFile )

<UserControl ...
             xmlns:Models="clr-namespace:Octopus.Capturing.Models"
             x:Class="Octopus.Capturing.Views.Controls.PatientFile"
             ... >
 
<Label FontSize="10" 
       VerticalContentAlignment="Center" Foreground="White"
       Content="{Binding FileName}"/>

但是绑定不起作用。 当我运行该应用程序时,我得到了UserControl的结构(样式和从文件夹中读取的正确文件数),但没有绑定到文件名属性。

我在这里做错了什么?

您不应在视图 model 中拥有PatientFile UserControl的集合。相反,为此类用户控件 PatientFileViewModel 创建一个单独的视图PatientFileViewModel 实施INotifyPropertyChanged以启用通知控件更新已更改的属性。

public class PatientFileViewModel : INotifyPropertyChanged
{
   private string _fileName;
   public string FileName
   {
      get => _fileName;
      set
      {
         if (_fileName == value)
            return;

         _fileName = value;
         OnPropertyChanged();
      }
   }

   // ...implement the other properties like this, too.

   public event PropertyChangedEventHandler PropertyChanged;

   protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
   {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
   }
}

调整您的ItemTemplate以显示PatientFileViewModelPatientFile用户控件。

<ItemsControl.ItemTemplate>
   <DataTemplate DataType="{x:Type uc:PatientFileViewModel}">
      <uc:PatientFile/>
   </DataTemplate>
</ItemsControl.ItemTemplate>

接下来,从您的PatientFile用户控件中删除现在位于视图 model 中的属性和代码。 您可以保留其 XAML 代码。 Label的内容现在将绑定到数据上下文,即在应用DataTemplate时由ItemsControl自动设置的PatientFileViewModel

最后调整您的MainViewModel以创建和使用PatientFileViewModel而不是PatientFile

public class MainViewModel
{
   public ObservableCollection<PatientFileViewModel> PatientFiles { get; set; }

   public MainViewModel()
   {
      PatientFiles = new ObservableCollection<PatientFileViewModel>();

      if (!string.IsNullOrEmpty(Models.LocalSettings.SaveFolder) &&
          System.IO.Directory.Exists(Models.LocalSettings.SaveFolder))
      {
         var files = System.IO.Directory.GetFiles(Models.LocalSettings.SaveFolder);

         foreach (var p in files)
         {
            var n = p.Substring(p.LastIndexOf("\\") + 1, p.LastIndexOf(".") - p.LastIndexOf("\\") - 1);
            var ext = p.Substring(p.LastIndexOf(".") + 1);

            PatientFiles.Add(new PatientFileViewModel()
            {
               FileName = n,
               Path = p,
               FileType = ext == "avi" ? OutputType.Video : OutputType.Image
            });
         }
      }
   }
}

确保将主视图的DataContext设置为MainViewModel ,例如:

<Window xmlns:ViewModels="clr-namespace:Octopus.Capturing.ViewModels"x:Class="Octopus.Capturing.Views.MainApp"
        ...>
   <Window.DataContext>
      <ViewModels:MainViewModel/>
   </Window.DataContext>
   <!-- ...other code. -->
</Window>

此外,您应该删除ItemsSource绑定上的Mode=TwoWayUpdateSourceTrigger=PropertyChanged ,这不是必需的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM