【问题标题】:Binding to FontWeight in Silverlight 4 using a value converter在 Silverlight 4 中使用值转换器绑定到 FontWeight
【发布时间】:2011-03-07 23:17:46
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: silverlight xaml binding ivalueconverter


    【解决方案1】:

    您需要使用值转换器吗?我使用 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
    }
    

    【讨论】:

    • 感谢您的回复。 (抱歉耽搁了。我刚从一个短暂但非常需要的假期回来。:-))我将尝试这种方法以及下面 GreenIcicle 的建议。在值转换器中不需要这样做。但是,我正在尝试与 RIA 服务一起执行此操作。将上述 MVVM 方法与 RIA 服务一起使用时,我应该注意哪些注意事项?
    • 我试过了,它对我有用。 FWIW ...在 RIA 服务中,我可以使用 .shared 代码将“Value2FontWeight”属性(如上定义)添加到我的 DTO(在这种情况下,我认为它不再是最严格意义上的 DTO,但这没关系)。
    • FWIW... 将这种方法与 RIA 服务一起使用似乎有一个小问题(如果您不使用视图模型,那就是)。为客户端生成的代码为属性提供了自己的 setter 方法,因此在上述解决方案中对 OnPropertyChanged("Value2FontWeight") 的调用永远不会执行,因为它在生成的 setter 中不存在。
    【解决方案2】:

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

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

    【讨论】:

    • 感谢您的意见。 JSprang 的方法解决了这个问题,我喜欢您的建议,即通过将条件评估与 UI 中的指示方式分开来保持界面清洁。
    猜你喜欢
    • 2011-09-14
    • 2010-12-23
    • 2012-01-06
    • 1970-01-01
    • 2012-03-10
    • 2012-01-14
    • 2012-03-27
    • 2011-07-30
    • 1970-01-01
    相关资源
    最近更新 更多