【发布时间】:2021-10-03 13:36:09
【问题描述】:
在 WPF 窗口中,我显示了一个带有复选框的树视图,其中包含 Pc 上的磁盘/目录。当用户展开一个节点时,一个事件调用 folder_Expanded 添加该节点的子目录。
应该发生的是某些目录显示颜色(这有效),如果在 XML 文件中找到某些目录,则会检查它们。然后,用户可以选中或取消选中(子)目录,之后修改的目录选择再次存储在该 xml 文件中。
但是,我无法使用某个目录检查该 treeviewitem 中的复选框。在展开事件的代码中,我用一个示例目录对其进行了测试。背景颜色工作正常,但 IsSelected 行什么也没做。原因是 PropertyChanged 为 null,因此它不会创建 PropertyChangedEventArgs 的实例。我想说我拥有一切:从 INotifyPropertyChanged 继承并在 XAML 中分配为 DataContext 的模型,并通过此模型设置 XAML 中定义的 CheckBox 的属性 IsChecked。 我错过了什么?
或者我想知道我是否可以直接将复选框设置为选中,无需数据绑定,就像我设置背景颜色一样?数据绑定的问题是当它不起作用时,无法调试代码,它就是不起作用....
一开始:
SelectFilesModel selectFilesModel = new SelectFilesModel();
public SelectFiles()
{
InitializeComponent();
Window_Loaded();
}
void folder_Expanded(object sender, RoutedEventArgs e)
{
TreeViewItem item = (TreeViewItem)sender;
if (item.Items.Count == 1 && item.Items[0] == dummyNode)
{
item.Items.Clear();
try
{
foreach (string s in Directory.GetDirectories(item.Tag.ToString()))
{
TreeViewItem subitem = new TreeViewItem();
subitem.Header = s.Substring(s.LastIndexOf("\\") + 1);
subitem.Tag = s;
subitem.FontWeight = FontWeights.Normal;
subitem.Items.Add(dummyNode);
subitem.Expanded += new RoutedEventHandler(folder_Expanded);
if (s.ToLower() == "c:\\temp") // Sample directory to test
{
subitem.Background = Brushes.Yellow; // This works!
selectFilesModel.IsChecked = true; // Eventually PropertyChanged is always null!!
}
item.Items.Add(subitem);
}
}
catch (Exception e2)
{
MessageBox.Show(e2.Message + " " + e2.InnerException);
}
}
}
XAML 如下所示:
<Window.DataContext>
<local:SelectFilesModel/>
</Window.DataContext>
<Grid>
<TreeView x:Name="foldersItem" SelectedItemChanged="foldersItem_SelectedItemChanged" Width="Auto" Background="#FFFFFFFF" BorderBrush="#FFFFFFFF" Foreground="#FFFFFFFF">
<TreeView.Resources>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Name="img" Width="20" Height="20" Stretch="Fill"
Source="{Binding
RelativeSource={RelativeSource
Mode=FindAncestor,
AncestorType={x:Type TreeViewItem}},
Path=Header,
Converter={x:Static local:HeaderToImageConverter.Instance}}"
/>
<TextBlock Name="DirName" Text="{Binding}" Margin="5,0" />
<CheckBox Name="cb" Focusable="False" IsThreeState="True" IsChecked="{Binding IsChecked ,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center"/> </StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</TreeView.Resources>
</TreeView>
</Grid>
模型如下:
public class SelectFilesModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
bool? _isChecked = false;
public bool? IsChecked
{
get { return _isChecked; }
set { this.SetIsChecked(value, true, true); }
}
void SetIsChecked(bool? value, bool updateChildren, bool updateParent)
{
if (value == _isChecked)
return;
_isChecked = value;
RaisePropertyChanged("IsChecked");
}
void RaisePropertyChanged(string prop)
{
if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(prop)); }
}
} // SelectFilesModel
【问题讨论】:
-
您有两个 SelectFilesModel 实例,一个在 XAML 中声明为窗口的 DataContext,另一个在后面的代码中创建。删除 XAML 声明并在 SelectFiles 构造函数中设置
DataContext = selectFilesModel;。 -
感谢 Clemens,但我也已经尝试过了(稍后添加了 XAML 代码)。仍然 PropertyChanged 仍然为空。还有其他建议吗?