当从可观察集合更改为UI时,添加IValueConverter会中断更新

时间:2011-03-22 20:04:49

标签: c# wpf

我有一个itemcontrol,项目模板设置为边框,然后我将listview的datacontext绑定到包含bool属性的对象列表。

然后我向边框添加了一个单击事件处理程序,当检测到单击时,我将边框的datacontext强制转换为类,并将bool字段设置为true。

这可以作为一个魅力,但我希望当bool字段设置为true或false时矩形具有特定的颜色,所以我创建了一个IValueConverter,它接受我的类并返回一个颜色。 这也是有效的,矩形是基于bool场的不同颜色。

我仍然可以点击矩形,但它们没有更新。 矩形的颜色不会改变。

来自itemscontrol itemtemplate的数据模板

            <DataTemplate>
                <Border ToolTip="{Binding Seat.Column}" Width="25" Height="25" Margin="0,0,2,2" BorderBrush="Black" Background="{Binding Converter={StaticResource ResourceKey=SeatStateConverter}}" BorderThickness="2" Name="rectangle1" VerticalAlignment="Center" HorizontalAlignment="Center" MouseLeftButtonDown="rectangle1_MouseLeftButtonDown">
                    <Label Content="{Binding Occupied}" Foreground="White" FontSize="7"></Label>
                </Border>
            </DataTemplate>

点击事件

    private void rectangle1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Border item = sender as Border;
        SeatState state = item.DataContext as SeatState;

        state.Locked = !state.Locked;
    }

我的转换器

        public object Convert(object value, Type targetType, object parameter,   System.Globalization.CultureInfo culture)
        {
            SeatState state = value as SeatState;
            if (state == null)
                return null;

            SolidColorBrush brush = new SolidColorBrush();

            if (state.Occupied)
            {
                brush.Color = Color.FromRgb(172, 0,0);
            }
            else if (state.Locked)
            {
                brush.Color = Color.FromRgb(214, 65, 0);
            }
            else if(!state.Occupied)
            {
                brush.Color = Color.FromRgb(0, 172, 0);
            }

            return brush;
        }

这很有用..直到我添加将对象转换为SolidColorBrush的转换器。

我尝试了各种与我的问题无关的疯狂东西。

  • 实现convertback方法 在IValueConverter界面
  • 将绑定设置为双向绑定
  • 调用UpdateLayout ItemsControl上的方法

但似乎没有任何效果。

有人有任何想法吗? 我的英语可能会更好,所以请问是否有任何你想要澄清的东西=)

提前致谢。

2 个答案:

答案 0 :(得分:2)

我认为你绑定了SeatState对象 - 而你实际上需要绑定OccupiedLocked属性的某些组合?

即。它不是SeatState对象本身正在改变,而是SeatState的几个属性。

也许以某种方式将属性合并在一起,并将此合并属性设置为XAML背景的路径。

e.g。在SeatState中

private bool _Locked
public bool Locked
{
get
{
   return _Locked;
}
set
{
   _Locked = value;
   NotifyPropertyChange("Locked");
   NotifyPropertyChange("LockedAndOccupied");
}
}

private bool _Occupied
public bool Occupied
{
get
{
   return _Occupied;
}
set
{
   _Occupied = value;
   NotifyPropertyChange("Occupied");
   NotifyPropertyChange("LockedAndOccupied");
}
}

public Tuple<bool, bool> LockedAndOccupied
{
   get
   {
       return new Tuple<bool, bool>(Locked, Occupied);
   }
}

然后在XAML中,您可以绑定到Path=LockedAndOccupied, Converter=...

显然你也必须改变转换器代码 - 我会让你这样做!


或者......现在我已经读完了......

有一种称为MultiBinding的东西 - http://www.switchonthecode.com/tutorials/wpf-tutorial-using-multibindings - 看起来非常适合您的需求

类似的东西:

<Border.Background>
<MultiBinding Converter="{StaticResource aNewConverter}">
   <Binding Path="Locked"/>
   <Binding Path="Occupied"/>
</MultiBinding> 
</Border.Background>

今晚我学到了一些东西:)

答案 1 :(得分:0)

检查后台绑定......看起来你的路径丢失了。我期待看到类似......

Background="{Binding Path=., Converter={StaticResource ResourceKey=SeatStateConverter}}"

或者,您可以尝试设置BindsDirectlyToSource = true。

第二个想法,你可能需要实现一个IMultiValueConverter,然后分别绑定每个属性。这可能是您需要做的,以获取每个属性的更改通知。 Here is an example of an IMultiValueConverter implementation from MSDN.

另外,您可能想检查一下INotifyPropertyChanged的实现...属性名称拼写错误会破坏更改通知......