将可观察到的类对象集合绑定到列表框和用户控件(WPF)

时间:2020-07-05 06:50:28

标签: c# wpf xaml binding listbox

我要做什么

我将一个名为“ LBShortcuts ”的列表框绑定到一个名为“ ShortcutList ”的类,该类都继承了ObservableCollection<T>并保存了该类的对象< strong>快捷方式。我通过在DataContext的构造函数中设置ListBox的MainWindow来绑定它。然后,我有一个名为 UCShortcut 的UserControl作为DataTemplate,它绑定了 Shortcut 对象中的一个属性。当我单击主窗口上的按钮时,它应向ObservableCollection添加快捷方式,该快捷方式应调用CollectionChanged事件,然后该事件应警告数据绑定的ListBox更新其列表,然后更新其所有项

正在发生的事情:

绝对没有。当我尝试通过窗口上的按钮将快捷方式添加到列表时,它将快捷方式添加到列表中,但没有任何显示。我什至已将MainWindow的对象注册到ObservableCollection.CollectionChanged事件中,但是即使我显式调用它,它也似乎不会触发。因此,列表中没有任何内容。

我尝试过的事情:

  • 我尝试使用INotifyPropertyChangedINotifyCollectionChanged接口创建自定义列表类。
  • 我尝试使用System.Diagnostics.PresentationTraceLevel调试绑定过程,并将其设置在“立即”窗口中。不记得我哪里出了问题,但这没用。
  • 我试图更改调试选项,以向我展示有关WPF应用程序中绑定的所有信息,但所做的只是向我展示与以下内容无关的令人担忧的绑定失败:
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=IsInAppMenuExpanded; DataItem=null; target element is 'StackPanel' (Name='ButtonStackPanel'); target property is 'Visibility' (type 'Visibility')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=ShowLiveVisualTreeCommand; DataItem=null; target element is 'Button' (Name='ShowLiveVisualTree'); target property is 'Command' (type 'ICommand')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=IsInAppSelectionEnabled; DataItem=null; target element is 'ToggleButton' (Name='InAppSelection'); target property is 'IsChecked' (type 'Nullable`1')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=AreLayoutAdornersEnabled; DataItem=null; target element is 'ToggleButton' (Name='LayoutAdorners'); target property is 'IsChecked' (type 'Nullable`1')
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=IsTrackFocusedElementEnabled; DataItem=null; target element is 'ToggleButton' (Name='TrackFocusedElement'); target property is 'IsChecked' (type 'Nullable`1')

...我什至没有没有此应用程序中的切换按钮。

  • 我试图通过删除DataTempate来隔离绑定。
  • 我尝试将UCShortcut的TextBlock.Text绑定更改为{Binding BoundShortcut.Name, RelativeSource={RelativeSource AncestorType=UserControl}}
  • 我再次使用VS的数据绑定对话框尝试了相同的想法:{Binding BoundShortcut.Name, ElementName=userControl, FallbackValue=Binding Invalid}

我真的不确定我在做什么错。根据我所读到的所有内容,此应该可以正常工作。但是...我在这里。请帮忙吗?

详细信息

ListBox(LB快捷方式):

<Window xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase">
.
.
.
<ListBox x:Name="LBShortcuts" ItemsSource="{Binding}"
         Grid.Row="1" BorderBrush="{x:Null}" Background="{x:Null}" IsManipulationEnabled="True" AllowDrop="True" 
         diag:PresentationTraceSources.TraceLevel="High">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <local:UCShortcut BoundShortcut="{Binding Shortcut}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

ListBox的代码隐藏:

        public MainWindow()
        {
            InitializeComponent();
            Shortcuts = new ShortcutList();
            Shortcuts.CollectionChanged += SaveList;
            LBShortcuts.DataContext = Shortcuts;
            SavingPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) +
              "\\FolderShortcuts.json";
            OpenList();
        }

ShortcutList 类:

    public class ShortcutList : ObservableCollection<Shortcut>
    { 
        public ShortcutList() : base()
        {
            shortcuts = new List<Shortcut>();
        }

        public ShortcutList(List<Shortcut> loadedList) : base()
        {
            shortcuts = new List<Shortcut>();
            foreach (Shortcut sc in loadedList)
            {
                Add(new Shortcut(this,sc.Directory,sc.Name));
            }
        }

        public void AddDirectory(string directory, string name)
        {
          DirectoryInfo di = new DirectoryInfo(directory);
          Shortcut s = new Shortcut(this, di);
          if (shortcuts.Where(x => x.Directory == di.FullName).Count() == 0)
          {
              Add(s);
          }
        }
    }

快捷方式类:

    [Serializable]
    public class Shortcut : INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        public string Directory { get; set; }
        private string name;

        //This must be a property before you can use it as a data binding path in the properties menu of the design page
        public string Name
        {
            get {return name; }
            set
            {
                if (name != value)
                {
                    name = value;
                    OnPropertyChanged();
                }
            }
        }

        [NonSerialized]
        public ShortcutList Parent;

        private void OnPropertyChanged([CallerMemberName] string member_name = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(member_name));
        }

        public Shortcut(){ }

        public Shortcut(ShortcutList parent, DirectoryInfo directory)
        {
            Parent = parent;
            Directory = directory.FullName;
            Name = directory.Name;
        }

        public Shortcut(ShortcutList parent, string directory,string name)
        {
            Parent = parent;
            Directory = new DirectoryInfo(directory).FullName;
            Name = name;
        }
    }

UCShortCut (用户控件)

XAML:

<Grid VerticalAlignment="Center">
    ...
    <TextBlock x:Name="TBkName" Text="{Binding Name, FallbackValue=Binding Invalid}"
      Padding="4" Foreground="{DynamicResource ForegroundColor}"/>
    ...
</Grid>

隐藏代码:

 public partial class UCShortcut : UserControl
    {
        public static readonly DependencyProperty ShortcutProperty;
        public Shortcut BoundShortcut
        {
            get{ return (Shortcut)GetValue(ShortcutProperty); }
            set{ SetValue(ShortcutProperty, value); }
        }

        static UCShortcut()
        {
            ShortcutProperty = DependencyProperty.Register("BoundShortcut",
              typeof(Shortcut), typeof(UCShortcut));
        }

        public UCShortcut()
        {
            InitializeComponent();
        }

        private void RenameShortcut(object sender, RoutedEventArgs e)
        {
            TBxName.Text = TBkName.Text;
            TBkName.Visibility = Visibility.Collapsed;
            TBxName.Visibility = Visibility.Visible;
            TBxName.Focus();
            TBxName.SelectAll();
        }

        private void ChangeName(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter || e.Key == Key.Escape)
            {
                if (e.Key == Key.Enter)
                {
                    BoundShortcut.Name = TBxName.Text;
                }
                TBkName.Visibility = Visibility.Visible;
                TBxName.Visibility = Visibility.Collapsed;
                TBxName.Text = string.Empty;
            }
        }

        private void InitBoundShortcut(object sender, RoutedEventArgs e)
        {
            BoundShortcut = (Shortcut)DataContext;
        }
    }

0 个答案:

没有答案