我需要在我的WPF应用程序中添加水印,并使用this watermark service来实现它。
它的工作原理与预期一致,但我需要将显示为水印的文本本地化,我找不到实现它的方法。
我的xaml声明:
<TextBox
Text="{Binding Name, Mode=TwoWay}">
<Watermark:WatermarkService.Watermark>
<TextBlock
Text="{Binding <What-goes-here?>}"
/>
</Watermark:WatermarkService.Watermark>
</TextBox>
我的ViewModel:
public class PersonViewModel
{
public string Name {get;set;}
public string NameWatermark {get;set;}
}
以下几行不起作用:
Text="{Binding NameWatermark}"
<Window x:Name="ThisWindow"
...
Text="{Binding Path=NameWatermark,
ElementName=ThisWindow}"
有没有办法实现它?
任何帮助都将不胜感激,谢谢。
答案 0 :(得分:2)
我意识到这个问题很古老,但对于谷歌时间旅行者来说,我遇到了完全相同的问题并通过使用MultiDataTrigger
来隐藏/显示水印元素来解决它。它的工作原理是因为它没有将元素嵌入到原始Watermark:WatermarkService.Watermark
之类的装饰器中。
<Grid>
<TextBox x:Name="messageBox" Text="{Binding Message, UpdateSourceTrigger=PropertyChanged}" Padding="5">
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding SendMessageCommand}"/>
</TextBox.InputBindings>
</TextBox>
<TextBlock Text="{text:Translate Key=WriteMessageWatermark}" IsHitTestVisible="False" Foreground="LightGray" Margin="7,6,0,0">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Collapsed" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=messageBox, Path=Text.IsEmpty}" Value="True" />
<Condition Binding="{Binding ElementName=messageBox, Path=IsFocused}" Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Grid>
答案 1 :(得分:0)
我认为问题是WatermarkService只是一个静态类而没有依赖对象,因此不会将DataContext正确地继承到其内容。
首先:你真的需要绑定到ViewModel吗?我假设您想要本地化UI的更多部分,因此将这些内容移动到专用服务将是一种选择。
这样的事情:
<Watermark:WatermarkService.Watermark>
<TextBlock Text="{Binding Source={x:Static Watermark:LocalizationService.Instance}, Path=[123],FallbackValue='No LocalizationService found'}"/>
</Watermark:WatermarkService.Watermark>
本地化的单例类:
private static volatile LocalizationService _instance;
private static object syncRoot = new Object();
public static LocalizationService Instance
{
get
{
if (_instance == null)
{
lock (syncRoot)
{
if (_instance == null)
_instance = new LocalizationService();
}
}
return _instance;
}
}
public string this[int id]
{
get
{
// do localization stuff here ...
return "Localized Value " + id;
}
}
}
如果您真的想要绑定到窗口的DataContext,可以使用以下解决方法:将ViewModel分配给ObjectDataprovider并在绑定中访问它:
<Grid Loaded="Grid_Loaded">
<Grid.Resources>
<ObjectDataProvider x:Key="PersonViewModelProvider" ObjectInstance="{x:Null}" IsAsynchronous="True"/>
</Grid.Resources>
<TextBox Text="{Binding Name, Mode=TwoWay}">
<Watermark:WatermarkService.Watermark>
<TextBlock Text="{Binding Source={StaticResource PersonViewModelProvider}, Path=NameWatermark}"/>
</Watermark:WatermarkService.Watermark>
</TextBox>
</Grid>
代码背后:
private void Grid_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
var panel = sender as Panel;
if (panel != null)
{
var objDataProvider = panel.Resources["PersonViewModelProvider"] as ObjectDataProvider;
objDataProvider.ObjectInstance = panel.DataContext;
}
}