我要做什么:
我将一个名为“ LBShortcuts ”的列表框绑定到一个名为“ ShortcutList ”的类,该类都继承了ObservableCollection<T>
并保存了该类的对象< strong>快捷方式。我通过在DataContext
的构造函数中设置ListBox的MainWindow
来绑定它。然后,我有一个名为 UCShortcut 的UserControl作为DataTemplate
,它绑定了 Shortcut 对象中的一个属性。当我单击主窗口上的按钮时,它应向ObservableCollection添加快捷方式,该快捷方式应调用CollectionChanged
事件,然后该事件应警告数据绑定的ListBox更新其列表,然后更新其所有项
正在发生的事情:
绝对没有。当我尝试通过窗口上的按钮将快捷方式添加到列表时,它将快捷方式添加到列表中,但没有任何显示。我什至已将MainWindow的对象注册到ObservableCollection.CollectionChanged
事件中,但是即使我显式调用它,它也似乎不会触发。因此,列表中没有任何内容。
我尝试过的事情:
INotifyPropertyChanged
和INotifyCollectionChanged
接口创建自定义列表类。System.Diagnostics.PresentationTraceLevel
调试绑定过程,并将其设置在“立即”窗口中。不记得我哪里出了问题,但这没用。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')
...我什至没有没有此应用程序中的切换按钮。
{Binding BoundShortcut.Name, RelativeSource={RelativeSource AncestorType=UserControl}}
{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;
}
}