2010-06-24 5 views
5

Я хочу сравнить две версии различных свойств и полужирный один из них, если он не равен другому. Поскольку SL4 не поддерживает MultiBinding, я привязываю FontWeight к «.». так что весь контекст данных передается в преобразователь. Затем я использую параметр преобразователя, чтобы указать, какие поля сравнивать в конверторе. Пока что так хорошо ... Значения, которые не совпадают, выделены жирным шрифтом.Связывание с FontWeight в Silverlight 4 с использованием преобразователя значений

Проблема заключается в том, что полужирное свойство связано с текстовым полем, которое можно редактировать. Когда значение редактируется, я хочу, чтобы конвертер был «повторно активирован», чтобы вес шрифта был установлен в соответствии с новым значением. Этого не происходит. Как это можно сделать?

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

(я также попытался использовать режим = TwoWay, чтобы увидеть, если это будет делать трюк. Однако, TwoWay связывание не может быть использован, когда вы связываясь с «»)

ответ

2

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

MainPage.xaml

<UserControl x:Class="BindBoldText.MainPage" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
xmlns:local="clr-namespace:BindBoldText" 
mc:Ignorable="d" 
d:DesignHeight="300" d:DesignWidth="400"> 

<UserControl.DataContext> 
    <local:MainPage_ViewModel/> 
</UserControl.DataContext> 

<StackPanel> 
    <TextBlock Text="{Binding Value1, Mode=TwoWay}"/> 
    <TextBlock Text="{Binding Value2, Mode=TwoWay}" FontWeight="{Binding Value2FontWeight}"/> 
    <TextBox Text="{Binding Value2, Mode=TwoWay}" TextChanged="TextBox_TextChanged"/> 
</StackPanel> 

MainPage.xaml.cs

public partial class MainPage : UserControl 
{ 
    public MainPage() 
    { 
     InitializeComponent(); 

     this.viewModel = this.DataContext as MainPage_ViewModel; 
    } 

    private MainPage_ViewModel viewModel; 

    private void TextBox_TextChanged(object sender, TextChangedEventArgs e) 
    {    
     viewModel.Value2 = (sender as TextBox).Text; 
    } 
} 

MainPage_ViewModel.cs

public class MainPage_ViewModel : INotifyPropertyChanged 
{ 
    public string Value1 
    { 
     get { return value1; } 
     set 
     { 
      if (value1 != value) 
      { 
       value1 = value; 
       OnPropertyChanged("Value1"); 
      } 
     } 
    } 
    private string value1 = "Test"; 

    public string Value2 
    { 
     get { return value2; } 
     set 
     { 
      if (value2 != value) 
      { 
       value2 = value; 
       OnPropertyChanged("Value2"); 
       OnPropertyChanged("Value2FontWeight"); 
      } 
     } 
    } 
    private string value2 = "Test"; 

    public FontWeight Value2FontWeight 
    { 
     get 
     { 
      if (value2.Equals(value1)) 
      { 
       return FontWeights.Normal; 
      } 
      else 
      { 
       return FontWeights.Bold; 
      } 
     } 
    } 

    #region INotifyPropertyChanged Members 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    #endregion 
} 
+0

Спасибо за ваш ответ. (Извините за задержку. Я только что вернулся из короткого, но очень необходимого, отпуска. :-)) Я попробую этот подход вместе с предложением GreenIcicle ниже. Это не требование делать это в конвертере значений. Тем не менее, я пытаюсь сделать это совместно с RIA Services. Есть ли какие-либо оговорки, о которых мне следует знать при использовании подхода MVVM, как вы описали выше вместе с RIA Services? – MylesRip

+0

Я попробовал это, и это сработало для меня. FWIW ... В службах RIA я могу использовать код .shared, чтобы добавить свойство Value2FontWeight (как определено выше) к моему DTO (в этом случае я полагаю, что он больше не является DTO в строгом смысле слова, но это нормально). – MylesRip

+1

FWIW ... Кажется, есть небольшая проблема при использовании этого подхода с RIA Services (если вы не используете модель представления, то есть).Код, созданный для клиента, предоставляет свои собственные методы настройки для свойств, поэтому вызов OnPropertyChanged («Value2FontWeight») в вышеприведенном решении никогда не выполняется, потому что он не существует в сгенерированном сеттере. – MylesRip

0

В вашем решение, значение не обновляется, поскольку само свойство привязано ко всему контексту данных через «.». выражение. INotifyPropertyChanged может вызываться, но это событие означает, что одно свойство изменилось, и поскольку вы не указываете имя свойства в выражении привязки, система привязки данных не знает, что привязка должна быть обновлена ​​- она ​​не может посмотрите, что делает ваш конвертер значений.

Я думаю, что оценка JSprang намного лучше, не по крайней мере потому, что она обеспечивает лучшее разделение логики представления, которое можно протестировать из разметки. Чтобы продолжить работу с чистым интерфейсом, вы можете позволить ViewModel реализовать логическое свойство «ValuesAreSame», привязать данные к нему и использовать конвертер значений для применения фактического визуального стиля (в данном случае, веса шрифта).

+0

Спасибо за ввод. Подход JSprang решил проблему, и мне нравится ваше предложение, чтобы очистить интерфейс, отделив оценку состояния от того, как это указано в пользовательском интерфейсе. – MylesRip