Wpf Interaction Behavior in nested DataGrids MVVM pattern

huangapple go评论92阅读模式
英文:

Wpf Interaction Behavior in nested DataGrids MVVM pattern

问题

我已翻译你提供的代码部分,如下所示:

  1. 我有一个简单的`DataGrid`,其中`RowDetailsTemplate``DataTemplate`也是一个`DataGrid`
  2. 使用一个`behavior`以双向绑定模式将`DataGrid``SelectedItems`绑定到`ViewModel`中。
  3. `behavior`同时用于主`DataGrid`和主`DataGrid`行的详细信息。
  4. 我面临的问题是,子`DataGrids`中的`behaviors`似乎永远不会被引用,子`DataGrid`中的每个`DataGrid.SelectionChanged`事件总是引用主`DataGrid`中的`behavior`
  5. **视图**
  6. xmlns:i = "http://schemas.microsoft.com/xaml/behaviors"
  7. <DataGrid Name = "MainDataGrid"
  8. AutoGenerateColumns = "False"
  9. HorizontalScrollBarVisibility = "Disabled"
  10. Height = "Auto"
  11. ItemsSource = "{Binding ObCol_Model}"
  12. VerticalAlignment = "Stretch" CanUserAddRows = "false" BorderThickness = "1"
  13. AlternatingRowBackground = "#FFFFFFCC"
  14. HorizontalGridLinesBrush = "#FFA0A0A0"
  15. VerticalGridLinesBrush = "#FFA0A0A0"
  16. SelectionUnit = "FullRow"
  17. HeadersVisibility = "Column"
  18. GridLinesVisibility = "Horizontal"
  19. ColumnHeaderHeight = "25" IsReadOnly = "True" CanUserResizeRows = "False" RowHeight = "22" VerticalContentAlignment = "Center"
  20. BorderBrush = "DarkGray" HorizontalAlignment = "Left"
  21. RowDetailsVisibilityMode = "VisibleWhenSelected">
  22. <i:Interaction.Behaviors>
  23. <local:DataGridSelectedItemsBehavior SelectedItems = "{Binding SelectedItems}" />
  24. </i:Interaction.Behaviors>
  25. <DataGrid.Columns>
  26. <DataGridTextColumn Header = "Code" Binding = "{Binding Code}" Width = "80" />
  27. <DataGridTextColumn Header = "Name" Binding = "{Binding Name}" Width = "*" />
  28. </DataGrid.Columns>
  29. <DataGrid.RowDetailsTemplate>
  30. <DataTemplate>
  31. <DataGrid Name = "SubDataGrid"
  32. Margin = "10,0,0,0" AutoGenerateColumns = "False" ItemsSource = "{Binding ObCol_SubModel}"
  33. Height = "Auto" Width = "auto"
  34. VerticalAlignment = "Stretch" CanUserAddRows = "false" BorderThickness = "1"
  35. AlternatingRowBackground = "#FFFFFFCC"
  36. HorizontalGridLinesBrush = "#FFA0A0A0"
  37. VerticalGridLinesBrush = "#FFA0A0A0"
  38. SelectionUnit = "FullRow"
  39. HeadersVisibility = "Column"
  40. GridLinesVisibility = "Horizontal"
  41. ColumnHeaderHeight = "25" IsReadOnly = "True" CanUserResizeRows = "False" RowHeight = "22" VerticalContentAlignment = "Center"
  42. BorderBrush = "DarkGray" HorizontalAlignment = "Left">
  43. <i:Interaction.Behaviors>
  44. <local:DataGridSelectedItemsBehavior SelectedItems = "{Binding SubSelectedItems}" />
  45. </i:Interaction.Behaviors>
  46. <DataGrid.Style>
  47. <Style TargetType = "{x:Type DataGrid}">
  48. <Setter Property = "Visibility" Value = "Visible" />
  49. <Style.Triggers>
  50. <DataTrigger Binding = "{Binding ObCol_SubModel}" Value = "{x:Null}">
  51. <Setter Property = "Visibility" Value = "Collapsed" />
  52. </DataTrigger>
  53. </Style.Triggers>
  54. </Style>
  55. </DataGrid.Style>
  56. <DataGrid.Columns>
  57. <DataGridTextColumn Header = "Detail" Binding = "{Binding Detail}" Width = "80" />
  58. <DataGridTextColumn Header = "Detail Name" Binding = "{Binding Name}" Width = "150" />
  59. <DataGridTextColumn Header = "Comment" Binding = "{Binding Comment}" Width = "*" />
  60. </DataGrid.Columns>
  61. </DataGrid>
  62. </DataTemplate>
  63. </DataGrid.RowDetailsTemplate>
  64. </DataGrid>
  65. **行为(Behavior**
  66. public class DataGridSelectedItemsBehavior: Behavior <DataGrid>
  67. {
  68. protected override void OnAttached()
  69. {
  70. base.OnAttached();
  71. if (SelectedItems != null)
  72. {
  73. AssociatedObject.SelectedItems.Clear();
  74. foreach (var item in SelectedItems)
  75. {
  76. AssociatedObject.SelectedItems.Add(item);
  77. }
  78. }
  79. }
  80. public IList SelectedItems
  81. {
  82. get { return (IList)GetValue(SelectedItemsProperty); }
  83. set { SetValue(SelectedItemsProperty, value); }
  84. }
  85. public static readonly DependencyProperty SelectedItemsProperty =
  86. DependencyProperty.Register("SelectedItems", typeof(IList), typeof(DataGridSelectedItemsBehavior), new UIPropertyMetadata(null, SelectedItemsChanged));
  87. private static void SelectedItemsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
  88. {
  89. var behavior = o as DataGridSelectedItemsBehavior;
  90. if (behavior == null) return;
  91. var oldValue = e.OldValue as INotifyCollectionChanged;
  92. var newValue = e.NewValue as INotifyCollectionChanged;
  93. if (oldValue != null)
  94. {
  95. oldValue.CollectionChanged -= behavior.SourceCollectionChanged;
  96. behavior.AssociatedObject.SelectionChanged -= behavior.DataGridSelectionChanged;
  97. }
  98. if (newValue != null)
  99. {
  100. behavior.AssociatedObject.SelectedItems.Clear();
  101. foreach (var item in (IEnumerable) newValue)
  102. {
  103. behavior.AssociatedObject.SelectedItems.Add(item);
  104. }
  105. behavior.AssociatedObject.SelectionChanged += behavior.DataGridSelectionChanged;
  106. newValue.CollectionChanged += behavior.SourceCollectionChanged;
  107. }
  108. }
  109. private bool _isUpdatingTarget;
  110. private bool _isUpdatingSource;
  111. void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  112. {
  113. if (_isUpdatingSource)
  114. return;
  115. try
  116. {
  117. _isUpdatingTarget = true;
  118. if (e.OldItems != null)
  119. {
  120. foreach (var item in e.OldItems)
  121. {
  122. AssociatedObject.SelectedItems.Remove(item);
  123. }
  124. }
  125. if (e.NewItems != null)
  126. {
  127. foreach (var item in e.NewItems)
  128. {
  129. AssociatedObject.SelectedItems.Add(item);
  130. }
  131. }
  132. if (e.Action == NotifyCollectionChangedAction.Reset)
  133. {
  134. AssociatedObject.SelectedItems.Clear();
  135. }
  136. }
  137. finally
  138. {
  139. _isUpdatingTarget = false;
  140. }
  141. }
  142. private void DataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
  143. {
  144. if (_isUpdatingTarget)
  145. return;
  146. var selectedItems = this.SelectedItems;
  147. if (selectedItems == null)
  148. return;
  149. try
  150. {
  151. _isUpdatingSource = true;
  152. foreach (var item in e.RemovedItems)
  153. {
  154. selectedItems.Remove(item);
  155. }
  156. foreach (var item in e.AddedItems)
  157. {
  158. selectedItems.Add(item);
  159. }
  160. }
  161. finally
  162. {
  163. _isUpdatingSource = false;
  164. }
  165. }
  166. }
  167. **视图模型(ViewModel**
  168. public class ViewModel: ObservableObject
  169. {
  170. private readonly ObservableCollection <Model> myObCol_Model;
  171. private ObservableCollection <Model> mySelectedItems;
  172. public ViewModel()
  173. {
  174. mySelectedItems = new ObservableCollection <Model> ();
  175. myObCol_Model = new ObservableCollection <Model> ()
  176. {
  177. new Model("100", "Hundred"),
  178. new Model("200", "Two Hundred"),
  179. new Model("300", "Three Hundred")
  180. };
  181. var item = new Model("400", "Four Hundred");
  182. item.AddSubModel(new SubModel("10", "Ten", "sub 10"));
  183. item.AddSubModel(new SubModel("20", "Twenty", "sub 20"));
  184. item.AddSubModel(new SubModel("30", "Thirty", "sub 30"));
  185. myObCol_Model.Add(item);
  186. }
  187. public ObservableCollection <Model> ObCol_Model { get { return myObCol_Model; } }
  188. public ObservableCollection <Model> SelectedItems
  189. {
  190. get
  191. <details>
  192. <summary>英文:</summary>
  193. I have a simple `DataGrid` with `RowDetailsTemplate` where the `DataTemplate` is also a `DataGrid`.
  194. A `behavior` is used to bind in two way mode `DataGrid&#39;s SelectedItems` to the `ViewModel`.
  195. The `behavior` is used both in main `DataGrid` and in subs `DataGrids` which are details of the main `DataGrid` rows.
  196. I&#39;m facing the problem that the behaviors in sub DataGrids seems to be never be referenced and each `DataGrid.SelectionChanged` event in the sub DataGrid refers always to the behavior in the main DataGrid.
  197. **THE VIEW**
  198. xmlns:i=&quot;http://schemas.microsoft.com/xaml/behaviors&quot;
  199. &lt;DataGrid Name=&quot;MainDataGrid&quot;
  200. AutoGenerateColumns=&quot;False&quot;
  201. HorizontalScrollBarVisibility=&quot;Disabled&quot;
  202. Height=&quot;Auto&quot;
  203. ItemsSource=&quot;{Binding ObCol_Model}&quot;
  204. VerticalAlignment=&quot;Stretch&quot; CanUserAddRows=&quot;false&quot; BorderThickness=&quot;1&quot;
  205. AlternatingRowBackground=&quot;#FFFFFFCC&quot;
  206. HorizontalGridLinesBrush=&quot;#FFA0A0A0&quot;
  207. VerticalGridLinesBrush=&quot;#FFA0A0A0&quot;
  208. SelectionUnit=&quot;FullRow&quot;
  209. HeadersVisibility=&quot;Column&quot;
  210. GridLinesVisibility=&quot;Horizontal&quot;
  211. ColumnHeaderHeight=&quot;25&quot; IsReadOnly=&quot;True&quot; CanUserResizeRows=&quot;False&quot; RowHeight=&quot;22&quot; VerticalContentAlignment=&quot;Center&quot;
  212. BorderBrush=&quot;DarkGray&quot; HorizontalAlignment=&quot;Left&quot;
  213. RowDetailsVisibilityMode=&quot;VisibleWhenSelected&quot;&gt;
  214. &lt;i:Interaction.Behaviors&gt;
  215. &lt;local:DataGridSelectedItemsBehavior SelectedItems=&quot;{Binding SelectedItems}&quot; /&gt;
  216. &lt;/i:Interaction.Behaviors&gt;
  217. &lt;DataGrid.Columns&gt;
  218. &lt;DataGridTextColumn Header=&quot;Code&quot; Binding=&quot;{Binding Code}&quot; Width=&quot;80&quot;/&gt;
  219. &lt;DataGridTextColumn Header=&quot;Name&quot; Binding=&quot;{Binding Name}&quot; Width=&quot;*&quot;/&gt;
  220. &lt;/DataGrid.Columns&gt;
  221. &lt;DataGrid.RowDetailsTemplate&gt;
  222. &lt;DataTemplate&gt;
  223. &lt;DataGrid Name=&quot;SubDataGrid&quot;
  224. Margin=&quot;10,0,0,0&quot; AutoGenerateColumns=&quot;False&quot; ItemsSource=&quot;{Binding ObCol_SubModel}&quot;
  225. Height=&quot;Auto&quot; Width=&quot;auto&quot;
  226. VerticalAlignment=&quot;Stretch&quot; CanUserAddRows=&quot;false&quot; BorderThickness=&quot;1&quot;
  227. AlternatingRowBackground=&quot;#FFFFFFCC&quot;
  228. HorizontalGridLinesBrush=&quot;#FFA0A0A0&quot;
  229. VerticalGridLinesBrush=&quot;#FFA0A0A0&quot;
  230. SelectionUnit=&quot;FullRow&quot;
  231. HeadersVisibility=&quot;Column&quot;
  232. GridLinesVisibility=&quot;Horizontal&quot;
  233. ColumnHeaderHeight=&quot;25&quot; IsReadOnly=&quot;True&quot; CanUserResizeRows=&quot;False&quot; RowHeight=&quot;22&quot; VerticalContentAlignment=&quot;Center&quot;
  234. BorderBrush=&quot;DarkGray&quot; HorizontalAlignment=&quot;Left&quot;&gt;
  235. &lt;i:Interaction.Behaviors&gt;
  236. &lt;local:DataGridSelectedItemsBehavior SelectedItems=&quot;{Binding SubSelectedItems}&quot; /&gt;
  237. &lt;/i:Interaction.Behaviors&gt;
  238. &lt;DataGrid.Style&gt;
  239. &lt;Style TargetType=&quot;{x:Type DataGrid}&quot;&gt;
  240. &lt;Setter Property=&quot;Visibility&quot; Value=&quot;Visible&quot;/&gt;
  241. &lt;Style.Triggers&gt;
  242. &lt;DataTrigger Binding=&quot;{Binding ObCol_SubModel}&quot; Value=&quot;{x:Null}&quot;&gt;
  243. &lt;Setter Property=&quot;Visibility&quot; Value=&quot;Collapsed&quot;/&gt;
  244. &lt;/DataTrigger&gt;
  245. &lt;/Style.Triggers&gt;
  246. &lt;/Style&gt;
  247. &lt;/DataGrid.Style&gt;
  248. &lt;DataGrid.Columns&gt;
  249. &lt;DataGridTextColumn Header=&quot;Detail&quot; Binding=&quot;{Binding Detail}&quot; Width=&quot;80&quot;/&gt;
  250. &lt;DataGridTextColumn Header=&quot;Detail Name&quot; Binding=&quot;{Binding Name}&quot; Width=&quot;150&quot;/&gt;
  251. &lt;DataGridTextColumn Header=&quot;Comment&quot; Binding=&quot;{Binding Comment}&quot; Width=&quot;*&quot;/&gt;
  252. &lt;/DataGrid.Columns&gt;
  253. &lt;/DataGrid&gt;
  254. &lt;/DataTemplate&gt;
  255. &lt;/DataGrid.RowDetailsTemplate&gt;
  256. &lt;/DataGrid&gt;
  257. **THE BEHAVIOR**
  258. public class DataGridSelectedItemsBehavior : Behavior&lt;DataGrid&gt;
  259. {
  260. protected override void OnAttached()
  261. {
  262. base.OnAttached();
  263. if (SelectedItems != null)
  264. {
  265. AssociatedObject.SelectedItems.Clear();
  266. foreach (var item in SelectedItems)
  267. {
  268. AssociatedObject.SelectedItems.Add(item);
  269. }
  270. }
  271. }
  272. public IList SelectedItems
  273. {
  274. get { return (IList)GetValue(SelectedItemsProperty); }
  275. set { SetValue(SelectedItemsProperty, value); }
  276. }
  277. public static readonly DependencyProperty SelectedItemsProperty =
  278. DependencyProperty.Register(&quot;SelectedItems&quot;, typeof(IList), typeof(DataGridSelectedItemsBehavior), new UIPropertyMetadata(null, SelectedItemsChanged));
  279. private static void SelectedItemsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
  280. {
  281. var behavior = o as DataGridSelectedItemsBehavior;
  282. if (behavior == null) return;
  283. var oldValue = e.OldValue as INotifyCollectionChanged;
  284. var newValue = e.NewValue as INotifyCollectionChanged;
  285. if (oldValue != null)
  286. {
  287. oldValue.CollectionChanged -= behavior.SourceCollectionChanged;
  288. behavior.AssociatedObject.SelectionChanged -= behavior.DataGridSelectionChanged;
  289. }
  290. if (newValue != null)
  291. {
  292. behavior.AssociatedObject.SelectedItems.Clear();
  293. foreach (var item in (IEnumerable)newValue)
  294. {
  295. behavior.AssociatedObject.SelectedItems.Add(item);
  296. }
  297. behavior.AssociatedObject.SelectionChanged += behavior.DataGridSelectionChanged;
  298. newValue.CollectionChanged += behavior.SourceCollectionChanged;
  299. }
  300. }
  301. private bool _isUpdatingTarget;
  302. private bool _isUpdatingSource;
  303. void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  304. {
  305. if (_isUpdatingSource)
  306. return;
  307. try
  308. {
  309. _isUpdatingTarget = true;
  310. if (e.OldItems != null)
  311. {
  312. foreach (var item in e.OldItems)
  313. {
  314. AssociatedObject.SelectedItems.Remove(item);
  315. }
  316. }
  317. if (e.NewItems != null)
  318. {
  319. foreach (var item in e.NewItems)
  320. {
  321. AssociatedObject.SelectedItems.Add(item);
  322. }
  323. }
  324. if (e.Action == NotifyCollectionChangedAction.Reset)
  325. {
  326. AssociatedObject.SelectedItems.Clear();
  327. }
  328. }
  329. finally
  330. {
  331. _isUpdatingTarget = false;
  332. }
  333. }
  334. private void DataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
  335. {
  336. if (_isUpdatingTarget)
  337. return;
  338. var selectedItems = this.SelectedItems;
  339. if (selectedItems == null)
  340. return;
  341. try
  342. {
  343. _isUpdatingSource = true;
  344. foreach (var item in e.RemovedItems)
  345. {
  346. selectedItems.Remove(item);
  347. }
  348. foreach (var item in e.AddedItems)
  349. {
  350. selectedItems.Add(item);
  351. }
  352. }
  353. finally
  354. {
  355. _isUpdatingSource = false;
  356. }
  357. }
  358. }
  359. **THE VM**
  360. public class ViewModel : ObservableObject
  361. {
  362. private readonly ObservableCollection&lt;Model&gt; myObCol_Model;
  363. private ObservableCollection&lt;Model&gt; mySelectedItems;
  364. public ViewModel()
  365. {
  366. mySelectedItems = new ObservableCollection&lt;Model&gt;();
  367. myObCol_Model = new ObservableCollection&lt;Model&gt;()
  368. {
  369. new Model(&quot;100&quot;, &quot;Hundred&quot;),
  370. new Model(&quot;200&quot;, &quot;Two Hundred&quot;),
  371. new Model(&quot;300&quot;, &quot;Three Hundred&quot;)
  372. };
  373. var item = new Model(&quot;400&quot;, &quot;Four Hundred&quot;);
  374. item.AddSubModel(new SubModel(&quot;10&quot;, &quot;Ten&quot;, &quot;sub 10&quot;));
  375. item.AddSubModel(new SubModel(&quot;20&quot;, &quot;Twenty&quot;, &quot;sub 20&quot;));
  376. item.AddSubModel(new SubModel(&quot;30&quot;, &quot;Thirty&quot;, &quot;sub 30&quot;));
  377. myObCol_Model.Add(item);
  378. }
  379. public ObservableCollection&lt;Model&gt; ObCol_Model { get { return myObCol_Model; } }
  380. public ObservableCollection&lt;Model&gt; SelectedItems
  381. {
  382. get { return mySelectedItems; }
  383. set
  384. {
  385. if (mySelectedItems == value) return;
  386. mySelectedItems = value;
  387. OnPropertyChanged(nameof(SelectedItems));
  388. }
  389. }
  390. }
  391. **THE MODELS**
  392. public class Model : ObservableObject
  393. {
  394. private ObservableCollection&lt;SubModel&gt; myObCol_SubModel;
  395. private ObservableCollection&lt;SubModel&gt; mySubModelSelectedItems;
  396. public Model(string code, string name)
  397. {
  398. mySubModelSelectedItems = new ObservableCollection&lt;SubModel&gt;();
  399. Code = code;
  400. Name = name;
  401. }
  402. public string Code { get; set; }
  403. public string Name { get; set; }
  404. public ObservableCollection&lt;SubModel&gt; ObCol_SubModel { get { return myObCol_SubModel; } }
  405. public void AddSubModel(SubModel subModel)
  406. {
  407. if (myObCol_SubModel == null) myObCol_SubModel = new ObservableCollection&lt;SubModel&gt;();
  408. myObCol_SubModel.Add(subModel);
  409. }
  410. public ObservableCollection&lt;SubModel&gt; SubSelectedItems
  411. {
  412. get { return mySubModelSelectedItems; }
  413. set
  414. {
  415. if (mySubModelSelectedItems == value) return;
  416. mySubModelSelectedItems = value;
  417. OnPropertyChanged(nameof(SubSelectedItems));
  418. }
  419. }
  420. }
  421. public class SubModel
  422. {
  423. public SubModel(string detail, string name, string comment)
  424. {
  425. Detail = detail;
  426. Name = name;
  427. Comment = comment;
  428. }
  429. public string Detail { get; set; }
  430. public string Name { get; set; }
  431. public string Comment { get; set; }
  432. }
  433. </details>
  434. # 答案1
  435. **得分**: 1
  436. 下面是我翻译的代码部分:
  437. ```csharp
  438. 以下是我如何解决的问题:
  439. - 在`OnAttached()`中添加了`AssociatedObject.SelectionChanged += DataGridSelectionChanged;`,应该在调用`OnAttached()`后首先访问`AssociatedObject`,否则`AssociatedObject`为`null`。
  440. - 添加了`override OnDetaching()`。
  441. - 在依赖属性更改回调中添加了`behavior.AssociatedObject==null`检查。
  442. - 在`DataGridSelectionChanged`事件处理程序中添加了`e.Handled = true;`,以阻止事件冒泡,否则它将被父数据网格捕获。
  443. 我没有检查代码的其余部分,只修复了阻止选择工作的错误。

请注意,这是您提供的代码的翻译部分,不包括问题或其他内容。如果您有任何其他需求或问题,可以告诉我。

英文:

Below a behavior how it does work by me:

  1. public class DataGridSelectedItemsBehavior : Behavior&lt;DataGrid&gt;
  2. {
  3. protected override void OnAttached()
  4. {
  5. base.OnAttached();
  6. if (SelectedItems != null)
  7. {
  8. AssociatedObject.SelectedItems.Clear();
  9. foreach (var item in SelectedItems)
  10. {
  11. AssociatedObject.SelectedItems.Add(item);
  12. }
  13. }
  14. AssociatedObject.SelectionChanged += DataGridSelectionChanged;
  15. }
  16. protected override void OnDetaching()
  17. {
  18. base.OnDetaching();
  19. AssociatedObject.SelectionChanged -= DataGridSelectionChanged;
  20. }
  21. public IList SelectedItems
  22. {
  23. get { return (IList)GetValue(SelectedItemsProperty); }
  24. set { SetValue(SelectedItemsProperty, value); }
  25. }
  26. public static readonly DependencyProperty SelectedItemsProperty =
  27. DependencyProperty.Register(&quot;SelectedItems&quot;, typeof(IList), typeof(DataGridSelectedItemsBehavior), new UIPropertyMetadata(null, SelectedItemsChanged));
  28. private static void SelectedItemsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
  29. {
  30. var behavior = o as DataGridSelectedItemsBehavior;
  31. if (behavior == null || behavior.AssociatedObject==null)
  32. return;
  33. var oldValue = e.OldValue as INotifyCollectionChanged;
  34. var newValue = e.NewValue as INotifyCollectionChanged;
  35. if (oldValue != null)
  36. {
  37. oldValue.CollectionChanged -= behavior.SourceCollectionChanged;
  38. behavior.AssociatedObject.SelectionChanged -= behavior.DataGridSelectionChanged;
  39. }
  40. if (newValue != null)
  41. {
  42. behavior.AssociatedObject.SelectedItems.Clear();
  43. foreach (var item in (IEnumerable)newValue)
  44. {
  45. behavior.AssociatedObject.SelectedItems.Add(item);
  46. }
  47. behavior.AssociatedObject.SelectionChanged += behavior.DataGridSelectionChanged;
  48. newValue.CollectionChanged += behavior.SourceCollectionChanged;
  49. }
  50. }
  51. private bool _isUpdatingTarget;
  52. private bool _isUpdatingSource;
  53. void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
  54. {
  55. if (_isUpdatingSource)
  56. return;
  57. try
  58. {
  59. _isUpdatingTarget = true;
  60. if (e.OldItems != null)
  61. {
  62. foreach (var item in e.OldItems)
  63. {
  64. AssociatedObject.SelectedItems.Remove(item);
  65. }
  66. }
  67. if (e.NewItems != null)
  68. {
  69. foreach (var item in e.NewItems)
  70. {
  71. AssociatedObject.SelectedItems.Add(item);
  72. }
  73. }
  74. if (e.Action == NotifyCollectionChangedAction.Reset)
  75. {
  76. AssociatedObject.SelectedItems.Clear();
  77. }
  78. }
  79. finally
  80. {
  81. _isUpdatingTarget = false;
  82. }
  83. }
  84. private void DataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
  85. {
  86. if (_isUpdatingTarget)
  87. return;
  88. var selectedItems = this.SelectedItems;
  89. if (selectedItems == null)
  90. return;
  91. try
  92. {
  93. _isUpdatingSource = true;
  94. foreach (var item in e.RemovedItems)
  95. {
  96. selectedItems.Remove(item);
  97. }
  98. foreach (var item in e.AddedItems)
  99. {
  100. selectedItems.Add(item);
  101. }
  102. }
  103. finally
  104. {
  105. _isUpdatingSource = false;
  106. e.Handled = true;
  107. }
  108. }
  109. }

What was fixed?

  • Added AssociatedObject.SelectionChanged += DataGridSelectionChanged; to the OnAttached(), you should access AssociatedObject first after OnAttached() was called, otherwise AssociatedObject is null

  • Added override OnDetaching().

  • Added behavior.AssociatedObject==null check to the DP changed call back.

  • Added e.Handled = true; to the DataGridSelectionChanged event handler, in order to stop bubbling the event up, otherwise it comes by parent data grid.

I didn't check the rest of the code, just fixed errors which prevented selection to work.

huangapple
  • 本文由 发表于 2023年2月27日 03:08:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75574382.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定