这样做不对:
<MenuItem x:Uid="MenuItem_12" Header="400%" IsCheckable="True"
IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsValidZoomFactor}, ConverterParameter='400'}"/>
在我的Settings
我有一个整数ZoomFactor
。设置设置为公开,范围用户。
在我的XAML顶部,我有一个命名空间:
xmlns:Properties="clr-namespace:OCLMEditor.Properties"
这是我的ValueConverter
:
using System;
using System.Globalization;
using System.Windows.Data;
namespace OCLMEditor.ValueConverters
{
[ValueConversion(typeof(int), typeof(bool))]
public class IsCurrentZoomFactor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int desiredZoomFactor = (int)value;
int currentZoomFactor = (int)parameter;
return desiredZoomFactor == currentZoomFactor;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
但是我收到了一个错误:
1&gt; D:\ My Programs \ OCLMEditor \ OCLMEditor \ MainWindow.xaml(143,35):error MC3044:MarkupExtension表达式的结束'}'后面不允许显示文本'}'。第143行第35位。
我还有其他几个菜单项:
<MenuItem x:Uid="MenuItem_13" Header="300%" IsCheckable="True"/>
<MenuItem x:Uid="MenuItem_14" Header="250%" IsCheckable="True"/>
<MenuItem x:Uid="MenuItem_15" Header="200%" IsCheckable="True"/>
<MenuItem x:Uid="MenuItem_16" Header="175%" IsCheckable="True"/>
<MenuItem x:Uid="MenuItem_17" Header="150%" IsCheckable="True"/>
<MenuItem x:Uid="MenuItem_18" Header="125%" IsCheckable="True"/>
我不确定我是否采取正确的方式,但想法是:
此外,此时它被“更改”,因此另一个缩放因子,即要更新的设置。我认为绑定到“设置”是正确的方法。但是有错误。
我确认错误发生在IsChecked
行:
更新错误:
这个位本身没有视觉错误:
<MenuItem x:Uid="MenuItem_12" Header="400%" IsCheckable="True"
IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor}"/>
所以转换器/值的引入是错误的。
现在,我不得不改变我的转换器:
using System;
using System.Globalization;
using System.Windows.Data;
namespace OCLMEditor.ValueConverters
{
[ValueConversion(typeof(int), typeof(bool))]
public class IsCurrentZoomFactor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int currentZoomFactor = (int)value;
string strDesiredZoomFactor = (string)parameter;
int desiredZoomFactor = int.Parse(strDesiredZoomFactor);
return desiredZoomFactor == currentZoomFactor;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
因为我们正在传递'400',所以它是一个字符串。所以我必须将其转换为整数。如果我删除''它将不接受将其作为整数传递。
答案 0 :(得分:1)
你的问题是ConverterParameter。写一个没有撇号的参数
... ConverterParameter=400}"/>
另外,您必须使用Convert来获取整数值,如
int desiredZoomFactor = Convert.ToInt16(value);
答案 1 :(得分:1)
这里的麻烦似乎与Binding.ConverterParameter
是一个字符串这一事实有关,因为XAML解析器无法知道预期的类型。
这是一种使用强类型参数(或多个参数,如果您愿意)重写值转换器的方法。如果您可以将参数类型检查从代码中的运行时错误移动到IDE中的设计时消息,那么它总是一个胜利。
public class IsCurrentZoomFactor : MarkupExtension, IValueConverter
{
public int DesiredZoomFactor { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int currentZoomFactor = (int)value;
return DesiredZoomFactor == currentZoomFactor;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
并像这样使用它。请注意,我们不会将IsCurrentZoomFactor
的实例创建为资源。由于它是MarkupExtension
,我们在我们使用它的地方实例化它,我们也在那里初始化它的参数属性。这样做的好处是XAML解析器知道DesiredZoomFactor
是一个整数。
您可以这样使用它:
<MenuItem
x:Uid="MenuItem_12" Header="400%" IsCheckable="True"
IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={local:IsCurrentZoomFactor DesiredZoomFactor=400}}"
/>
这非常方便,因为它使值转换器自我记录。当您在XAML中键入{local:IsCurrentZoomFactor
时,XAML编辑器会为您提供其属性列表:
在你编写转换器六个月或两年后,试图记住参数是什么。如果属性类型是enum
,您甚至可以获取要从中选择的值列表。
顺便说一句,我会重命名这个转换器及其参数,以反映这样一个事实:如果一个整数等于另一个整数,它真正做的是返回true:
Converter={local:IsIntegerEqual To=400}
答案 2 :(得分:0)
感谢您的帮助。我现在有点工作了。
所以转换器看起来像这样:
using System;
using System.Globalization;
using System.Windows.Data;
namespace OCLMEditor.ValueConverters
{
[ValueConversion(typeof(int), typeof(bool))]
public class IsCurrentZoomFactor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int currentZoomFactor = (int)value;
string strDesiredZoomFactor = (string)parameter;
int desiredZoomFactor = int.Parse(strDesiredZoomFactor);
return desiredZoomFactor == currentZoomFactor;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return int.Parse((string)parameter);
//throw new NotImplementedException();
}
}
}
和XAML:
<MenuItem x:Uid="MenuItem_12" Header="400%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='400'}"/>
<MenuItem x:Uid="MenuItem_13" Header="300%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='300'}"/>
<MenuItem x:Uid="MenuItem_14" Header="250%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='250'}"/>
<MenuItem x:Uid="MenuItem_15" Header="200%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='200'}"/>
<MenuItem x:Uid="MenuItem_16" Header="175%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='175'}"/>
<MenuItem x:Uid="MenuItem_17" Header="150%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='150'}"/>
<MenuItem x:Uid="MenuItem_18" Header="125%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='125'}"/>
<MenuItem x:Uid="MenuItem_19" Header="100%" IsCheckable="True" InputGestureText="CTRL + 0" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='100'}">
<MenuItem.InputBindings>
<KeyBinding x:Uid="KeyBinding_9" Key="D0" Modifiers="Ctrl"/>
</MenuItem.InputBindings>
</MenuItem>
<MenuItem x:Uid="MenuItem_20" Header="75%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='75'}"/>
<MenuItem x:Uid="MenuItem_21" Header="50%" IsCheckable="True" IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=ZoomFactor, Converter={StaticResource IsCurrentZoomFactor}, ConverterParameter='50'}"/>
<Separator x:Uid="Separator_8"/>
<MenuItem x:Uid="MenuItem_22" Header="Custom..."/>
至少现在设置已正确保存。我知道我还有更多工作要做(比如将点击绑定到命令)。