我有一個ItemsControl創建CheckBox基于ES DigitalFilterSubsystems。每當CheckBox單擊a 時,我都想在視圖模型上觸發事件處理程式。在他們那一刻,我的Click財產CheckBox正在抱怨Checked_Triggered期待財產。有人可以解釋我做錯了什么并提供解決方案嗎?
<ItemsControl Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" ItemsSource="{Binding DigitalFilterSubsystems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock HorizontalAlignment="Center" Text="{Binding }" Foreground="Black" FontSize="12"/>
<CheckBox HorizontalAlignment="Center" Click="{Binding Path=Checked_Triggered, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type vm:SimulatorControlViewModel}}, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
在我的視圖模型中呼叫SimulatorControlViewModel:
public void Checked_Triggered(object sender, RoutedEventArgs e)
{
}
uj5u.com熱心網友回復:
首先,不能將事件處理程式系結到 XAML 中的事件。即使有可能,您的系結也是錯誤的。您的視圖模型設定為DataContext控制元件的 ,但RelativeSource用于參考控制元件。您要做的是將父控制元件的型別指定為AncestorType,它具有所需的資料背景關系集并指定屬性路徑DataContext.YourPropertyToBind,例如:
<CheckBox HorizontalAlignment="Center" IsChecked="{Binding DataContext.MyIsCheckPropertyOnTheViewModel, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
現在到您問題的核心,如果CheckBox Click引發事件,則在視圖模型中執行操作。有多種選擇,具體取決于您的要求。
公開屬性
如果您的專案DigitalFilterSubsystems是自定義型別,例如Subsystem,您可以公開一個屬性IsChecked(或為檢查的含義賦予一個更有意義的名稱)。在屬性的 setter 中,呼叫一個作用于屬性當前值的方法。
public class Subsystem : INotifyPropertyChanged
{
private bool _isChecked;
public bool IsChecked
{
get => _isChecked;
set
{
if (_isChecked == value)
return;
_isChecked = value;
OnPropertyChanged(nameof(IsChecked));
OnCheckedChanged();
}
}
private void OnCheckedChanged()
{
if (IsChecked)
// ...do something.
else
// ...do something.
}
// ...other code.
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
然后只需將 XAML 中的屬性系結到IsCheckedof CheckBox。
<CheckBox HorizontalAlignment="Center" IsChecked="{Binding IsChecked}"/>
使用命令
您可以使用命令來封裝邏輯并將其公開為可系結物件。為此,您需要一個中繼命令或通常稱為委托命令實作。您可以在以下文章中閱讀有關這些概念的詳細資訊。
- MVVM - 命令、RelayCommands 和 EventToCommand
A relay command simply takes an action that it encapsulates as an object and optionally a can execute predicate that determines if the action can be executed. This object can be exposed from a view model and bound in XAML. Relay commands implement the ICommand interface and WPF knows how to handle it.
You can copy a relay command implementation from anywhere, there are plenty of implementations, most MVVM frameworks already provide their own. If you have chosen one, expose a command property in your SimulatorControlViewModel and initialize it in the constructor with the method to be called (this could vary depending on the concrete command implementation that you use).
public class SimulatorControlViewModel : INotifyPropertyChanged
{
public SimulatorControlViewModel()
{
Clicked = new RelayCommand(ExecuteClicked);
}
public ICommand Clicked { get; }
private void ExecuteClicked(object isChecked)
{
if ((bool)isChecked)
// ...do something.
else
// ...do something.
}
// ...other code.
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
然后將Clicked命令系結到 的Command屬性,CheckBox并將其系結CommandParameter到自己的IsChecked屬性(這是傳遞給ExecuteChecked方法的引數。
<CheckBox HorizontalAlignment="Center" Command="{Binding Clicked, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding IsChecked, RelativeSource={RelativeSource Self}}"/>
使用行為呼叫方法
您可以安裝Microsoft.Xaml.Behaviors.Wpf NuGet 包,其中包含CallMethodAction允許在引發事件時在物件上呼叫方法。
<CheckBox HorizontalAlignment="Center">
<b:Interaction.Triggers>
<b:EventTrigger EventName="Click">
<b:CallMethodAction MethodName="Checked_Triggered" TargetObject="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}"/>
</b:EventTrigger>
</b:Interaction.Triggers>
</CheckBox>
注意:方法簽名必須public void Checked_Triggered()完全匹配( public, returnvoid和 no arguments),否則您將收到一個例外,指出該方法未找到。
uj5u.com熱心網友回復:
您不能以這種方式系結到方法,只能系結到屬性。根據您是否使用某種 MVVM 框架,該框架可能會提供解決方案。另一種方法是使用系結到視圖模型中定義的命令屬性。看看這里:https : //stackoverflow.com/a/3531935/1213316
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/313943.html
