使用值转换器绑定到Silverlight 4中的FontWeight

时间:2010-06-24 18:26:34

标签: silverlight xaml binding ivalueconverter

我想比较各种属性的两个版本,如果它不等于另一个,则要加粗其中一个。由于SL4不支持MultiBinding,我将FontWeight绑定到“。”。以便将整个数据上下文传递给转换器。然后,我使用converter参数指定要在转换器中比较的字段。到目前为止,这么好......不匹配的值是粗体。

问题是粗体属性绑定到可以编辑的文本框。编辑该值时,我希望“重新激活”转换器,以便根据 new 值设置字体粗细。这不会发生。如何实现这一目标?

注意:我已经为相关的类和属性实现了INotifyPropertyChanged。更改值后切换到下一个字段会导致PropertyChanged事件触发,但字体权重不会更新,直到我实际移动到另一个记录然后返回到已更改的记录

(我也尝试使用Mode = TwoWay来查看是否可以解决问题。但是,当您绑定到“。”时,不能使用TwoWay绑定。)

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分:0)

在您的解决方案中,值不会更新,因为属性本​​身通过“。”绑定到整个数据上下文。表达。可以调用INotifyPropertyChanged,但是此事件意味着单个属性已更改,并且由于您未在绑定表达式中提供属性名称,因此数据绑定系统不知道Binding需要更新 - 它不能看看你的价值转换器做了什么。

我认为JSprang的appraoch好多了,至少不是因为它提供了可以从标记测试的更好的表示逻辑分离。为了进一步使用干净的接口,您可以让ViewModel实现一个布尔属性“ValuesAreSame”,对其进行数据绑定,并使用值转换器来应用实际的视觉样式(在本例中为字体粗细)。 p>