Привязать TextBox.Text к вложенному свойству Watermark, чтобы локализовать его - PullRequest
2 голосов
/ 14 марта 2012

Мне нужно добавить водяные знаки в мое приложение WPF, и я использую этот сервис водяных знаков для его достижения.

Он работает так, как ожидалось, но мне нужно локализовать текст, отображаемый какВодяной знак, и я не могу найти способ достичь этого.

Моя декларация 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;}
}

Thw следующие строки НЕ работают:

Text="{Binding NameWatermark}"

<Window x:Name="ThisWindow"
...
Text="{Binding Path=NameWatermark,
               ElementName=ThisWindow}"

Есть ли способ достичь этого?

Буду признателен за любую помощь, спасибо.

Ответы [ 2 ]

2 голосов
/ 19 сентября 2017

Я понимаю, что этот вопрос древний, но для путешественников во времени в Google, я столкнулся с той же самой проблемой и решил ее, используя 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>
0 голосов
/ 14 марта 2012

Я думаю, что проблема в том, что WatermarkService - это просто статический класс, и он не является объектом зависимости и поэтому не наследует DataContext должным образом для его содержимого.

Сначала: вам действительно нужно привязаться к ViewModel?Я предполагаю, что вы хотите локализовать больше частей вашего пользовательского интерфейса, поэтому можно переместить этот материал в выделенную службу.

Примерно так:

<Watermark:WatermarkService.Watermark>
  <TextBlock Text="{Binding Source={x:Static Watermark:LocalizationService.Instance}, Path=[123],FallbackValue='No LocalizationService found'}"/>
</Watermark:WatermarkService.Watermark>

Класс Singleton для локализации:

    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;
  }
}
...