我有一個自定義用戶控制元件,它有一個復選框和一個帶有支持依賴屬性的按鈕。
我還有一個帶有 ItemsControl 的視窗,我將該控制元件的“ItemsSource”系結到包含所述用戶控制元件的 ObservableCollection。
我的目標是能夠訪問視窗視圖模型中的依賴項屬性,因此我可以檢查集合中每個成員的復選框是否被選中以及當用戶單擊按鈕時 - 洗掉包含按鈕的用戶控制元件集合。
這是我的代碼
用戶控制 XAML:
<CheckBox IsChecked="{Binding cbChecked,
Mode=OneWayToSource,
UpdateSourceTrigger=PropertyChanged,
RelativeSource={RelativeSource FindAncestor,
AncestorType=UserControl}}"/>
<Button Content="X"
Command="{Binding RemoveCommand,
RelativeSource={RelativeSource FindAncestor,
AncestorType=UserControl}}">
(注意我不確定是否需要“UpdateSourceTrigger”)
用戶控制代碼隱藏:
public ICommand RemoveCommand
{
get { return (ICommand)GetValue(RemoveCommandProperty); }
set { SetValue(RemoveCommandProperty, value); }
}
// Using a DependencyProperty as the backing store for RemoveCommand. This enables animation, styling, binding, etc...
public static readonly DependencyProperty RemoveCommandProperty =
DependencyProperty.Register("RemoveCommand", typeof(ICommand), typeof(CustomUserControl), new PropertyMetadata(OnAnyPropertyChanged));
public bool cbChecked
{
get { return (bool)GetValue(cbCheckedProperty); }
set { SetValue(cbCheckedProperty, value); }
}
// Using a DependencyProperty as the backing store for cbChecked. This enables animation, styling, binding, etc...
public static readonly DependencyProperty cbCheckedProperty =
DependencyProperty.Register("cbChecked", typeof(bool), typeof(CustomUserControl), new PropertyMetadata(OnAnyPropertyChanged));
static void OnAnyPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
=> (obj as CustomUserControl).OnAnyPropertyChanged(args);
void OnAnyPropertyChanged(DependencyPropertyChangedEventArgs args)
=> AnyPropertyChanged?.Invoke(this, args);
視窗 XAML:
<ScrollViewer VerticalScrollBarVisibility="Visible" Grid.Row="0">
<ItemsControl ItemsSource="{Binding ControlsCollection}" HorizontalAlignment="Stretch" VerticalAlignment="Top">
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="FrameworkElement.Margin" Value="5,20,0,0"/>
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
</ScrollViewer>
我怎樣才能做到這一點,當用戶單擊“X”按鈕時,持有它的用戶控制元件將從集合中洗掉,并且能夠從視窗的視圖模型中檢查復選框“已檢查”狀態?
uj5u.com熱心網友回復:
首先,您不應該在視圖模型中持有視圖元素。ObservableCollection 的 item 應該是 item 的 view model 而不是 UserControl。
其次,在這種情況下,您不需要使用 UserControl。具有相同元素的 DataTemplate 就足夠了。
例如,最小專案的視圖模型如下。
using CommunityToolkit.Mvvm.ComponentModel;
public partial class ItemViewModel : ObservableObject
{
[ObservableProperty]
public bool _checked;
}
然后,視窗的視圖模型。
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
public class MainWindowViewModel : ObservableObject
{
public ObservableCollection<ItemViewModel> ItemsCollection { get; } = new();
public MainWindowViewModel()
{
ItemsCollection.Add(new ItemViewModel());
ItemsCollection.Add(new ItemViewModel());
ItemsCollection.Add(new ItemViewModel());
}
public ICommand RemoveCommand => _removeCommand ??= new RelayCommand<ItemViewModel>(item => Remove(item));
private RelayCommand<ItemViewModel>? _removeCommand;
private void Remove(ItemViewModel? item)
{
if (item is not null)
{
Debug.WriteLine($"Checked:{item.Checked}");
ItemsCollection.Remove(item);
}
}
}
窗戶的景色。ItemsControl.ItemTemplate 的 DataTemplate 的元素與您的 UserControl 相同,但修改了系結。
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp"
Title="MainWindow"
Width="600" Height="300">
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<ScrollViewer VerticalScrollBarVisibility="Visible">
<ItemsControl ItemsSource="{Binding ItemsCollection}"
HorizontalAlignment="Stretch" VerticalAlignment="Top">
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="FrameworkElement.Margin" Value="5,20,0,0"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox IsChecked="{Binding Checked, Mode=OneWayToSource}"/>
<Button Content="X"
Command="{Binding DataContext.RemoveCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
CommandParameter="{Binding DataContext, RelativeSource={RelativeSource Self}}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Window>
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/513552.html
標籤:C#wpfxml依赖属性
