gpt4 book ai didi

c# - WPF 交互命令引用转换器的本地静态资源

转载 作者:行者123 更新时间:2023-11-30 12:21:06 34 4
gpt4 key购买 nike

我希望创建一个具有行为属性的“可重用”控件项。如所述in this blog

对于数据绑定(bind),必须转换数据。问题是;作为 StaticResource,它只能看到顶级字典(app),动态资源不起作用(“只能与依赖属性一起使用”)。

简单(工作)xaml(窗口):

<Window x:Class="testit.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Rectangle x:Name="blah" Fill="Yellow" Stroke="Black" Width="100" Height="100">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter" >
<i:InvokeCommandAction Command="{Binding MouseEnterCommand}">
<i:InvokeCommandAction.CommandParameter>
<Binding Path="Name"
Converter="{StaticResource SelectionConverter}"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Rectangle}" />
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>
<TextBlock x:Name="namefield" Text="{Binding Data}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
</Window>

应用:

<Application x:Class="testit.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:testit"
StartupUri="MainWindow.xaml">
<Application.Resources>
<local:SelectionConverter x:Key="SelectionConverter" />
</Application.Resources>
</Application>

最后是 View 模型:

using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Data;

namespace testit
{
class ViewModel : INotifyPropertyChanged
{
private string _data;
private readonly DelegateCommand<string> _mouseEnterCommand = null;

public ViewModel() {
_data = "hello ";
_mouseEnterCommand = new DelegateCommand<string>(
(s) => {
var a = s ?? "world ";
Data += s;
return;
});
}

public DelegateCommand<string> MouseEnterCommand => _mouseEnterCommand;

public string Data {
get { return _data; }
set {
if (value == _data) return;
_data = value;
OnPropertyChanged("Data");
}
}


public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class SelectionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
if (value == null) return "";
char[] charArray = ((string)value).ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
throw new NotImplementedException();
}
}
}

现在如前所述,这“有效”。但是它并没有按照我的意愿行事:它使顶级资源字典变得困惑。我想从应用程序中删除资源。并将其放在网格下。 (或者我使用的任何面板)。

<Grid.Resources>
<local:SelectionConverter x:Key="SelectionConverter" />
</Grid.Resources>

编辑:如果我将上面的行添加到窗口内的网格中,编译时会抛出以下错误(行和位置引用 Converter="{StaticResource SelectionConverter}")

"'Provide value on 'System.Windows.StaticResourceExtension' threw an exception.' Line number '13' and line position '38'."

内部异常:

Cannot find resource named 'SelectionConverter'. Resource names are case sensitive.

为清楚起见,这是修改后的 window.xaml:

<Window x:Class="testit.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:local="clr-namespace:testit"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Rectangle x:Name="blah" Fill="Yellow" Stroke="Black" Width="100" Height="100">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter" >
<i:InvokeCommandAction Command="{Binding MouseEnterCommand}">
<i:InvokeCommandAction.CommandParameter>
<Binding Path="Name"
Converter="{StaticResource SelectionConverter}"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Rectangle}" />
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>
<TextBlock x:Name="namefield" Text="{Binding Data}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Grid.Resources>
<local:SelectionConverter x:Key="SelectionConverter" />
</Grid.Resources>
</Grid>
</Window>

最佳答案

当调用 ProvideValue 时,StaticResource 标记扩展会立即解析资源:

Lookup behavior for that resource is analogous to load-time lookup, which will look for resources that were previously loaded from the markup of the current XAML page

如果 Grid.Resources 是在 Grid 的内容之后定义的,那么当内容Grid 被解析。

因此,将资源放在网格的顶部,以便在使用之前定义其中的任何内容:

<Grid>
<Grid.Resources>
<local:SelectionConverter x:Key="SelectionConverter" />
</Grid.Resources>

<Rectangle x:Name="blah" Fill="Yellow" Stroke="Black" Width="100" Height="100">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter" >
<i:InvokeCommandAction Command="{Binding MouseEnterCommand}">
<i:InvokeCommandAction.CommandParameter>
<Binding Path="Name"
Converter="{StaticResource SelectionConverter}"
RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Rectangle}" />
</i:InvokeCommandAction.CommandParameter>
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Rectangle>
<TextBlock x:Name="namefield" Text="{Binding Data}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>

如果您能够使用 DynamicResource,您会很好,但当然您不能,因为您发现的原因。

关于c# - WPF 交互命令引用转换器的本地静态资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47420546/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com