【问题标题】:Change ListView Forecolor depending on condition根据条件更改 ListView 前景色
【发布时间】:2013-12-26 17:52:00
【问题描述】:

我是 WPF 的新手,所以目前对这个概念很困惑。 我有一个股票程序,我想根据股票价格是上涨还是下跌来更改该单元格的前景色。

这是我当前的代码(省略了几件事):

public class Stock : INotifyPropertyChanged
{
    public Stock()
    {
        DaysLow = 0;
        DaysHigh = 0;
    }

    public List<string[]> StockInformation = new List<string[]>();

    public string Symbol { get; set; }

    private double _Bid;
    public double Bid
    {
        get { return _Bid; }
        set
        {
            // If _Bid < value, change fore color
            _Bid = value;
            DisplayCurrentPrice = String.Format("{0} / {1}", value, Ask);

        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string PropertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }
    }

    public override string ToString()
    {
        return Symbol;
    }
}

XAML:

        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="Height" Value="26" />
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.View>
            <GridView AllowsColumnReorder="False">
                <GridViewColumn Header="Symbol" DisplayMemberBinding="{Binding Path=Symbol}" Width="120" />
                <GridViewColumn Header="Bid / Ask" DisplayMemberBinding="{Binding Path=DisplayCurrentPrice}" Width="125" />
                <GridViewColumn Header="D.High" DisplayMemberBinding="{Binding Path=DaysHigh}" Width="75" />
                <GridViewColumn Header="D.Low" DisplayMemberBinding="{Binding Path=DaysLow}" Width="75" />
                <GridViewColumn Header="Year Low/High" DisplayMemberBinding="{Binding Path=DisplayYearPrice}" Width="100" />
            </GridView>
        </ListView.View>
        <ListView.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Details" Click="CM_Details_Click"></MenuItem>
            </ContextMenu>
        </ListView.ContextMenu>
    </ListView>

那么我可以在这里做些什么来实现我正在寻找的东西?任何帮助表示赞赏,谢谢!

【问题讨论】:

  • 更改 ForeColor 哪个单元格以及在什么条件下?
  • 嗨 Rohit,我想更改单元格 DisplayCurrentPrice,条件是 Bid value = Red
  • 您需要在数据模型中添加一些内容来表示行应该是什么颜色并使用DataTrigger,或者使用IValueConverter 将您的数据转换为Foreground 的颜色财产。您可能需要一个IMultiValueConverter,这样您就可以将BidValue 参数传递给它,并让它返回您的颜色。这与IValueConverter 相同,但它接受多个参数。 :)
  • 是的,我明白现在需要做什么。假设我有一个公共画笔_Bruch {get;set;}。我如何将它绑定到 GridViewColumn?我是 XAML 最差的。

标签: c# .net wpf xaml data-binding


【解决方案1】:

这是我将如何代表我的 StockModel 班级:

class StockModel : INotifyPropertyChanged
{
    // NOTE: You must implement PropertyChanged notification for these properties...
    public string Symbol { get; set; }
    public decimal Bid { get; set; }
    public decimal Delta { get; set; }  // Change in price over time, +/-

    // Any additional properties you may want here...
}

现在,WPF 的美妙之处在于IValueConverter 类的形式。这些类允许您使用您提供的逻辑将值从一种类型“转换”为另一种类型。

在我们的例子中,我们希望将ListViewItem.Foreground 颜色绑定到StockModel.Delta 值。正的非零增量值应该给我们Green,负的非零增量值应该给我们Red。零可以保留为BlackWhite(取决于您主题的对比度)。

那么我们如何完成这样的事情呢?我们需要创建一个实现IValueConverterStockColorConverter类:

sealed class StockColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // Convert a delta value to a brush color.
        var deltaValue = System.Convert.ToDecimal(value);

        if (deltaValue > 0)
            return Brushes.Green;       // Positive
        else if (deltaValue < 0)
            return Brushes.Red;         // Negative 
        else
            return Brushes.Black;       // Zero
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        // We can't convert a color to a delta value! This will never be used anyhow.
        throw new NotSupportedException();
    }
}

现在,您需要在 XAML 中正确连接它。首先,假设您在MainWindow.xaml 文件中执行此操作。您需要在现有命名空间之后添加项目的命名空间:

xmlns:my="clr-namespace:WpfApplication1"

然后,创建(或附加到)Window.Resources

<Window.Resources>
    <my:StockColorConverter x:Key="StockColorConverter"/>
</Window.Resources>

使用DataTemplates 来处理ListViewItems 的布局要容易得多。 DataTemplate 决定了每个项目应该如何显示,以及应该显示什么:

        <ListView.ItemTemplate>
            <!-- These are StockModel objects as our data! -->
            <DataTemplate>
                <TextBlock Text="{Binding Symbol}"
                           Foreground="{Binding Delta, Converter={StaticResource StockColorConverter}}"/>
            </DataTemplate>
        </ListView.ItemTemplate>

您可以看到我们正在将TextBlock.Foreground 绑定到StockModel.Delta。通常这是行不通的,因为decimal 不等于Brush 对象。但是,使用我们创建的StockColorConverter,我们可以轻松应用条件格式。

【讨论】:

    【解决方案2】:

    你可以在你的c#中添加这个

    public bool ChangeColor {get; set;}
    
    private double _Bid;
    public double Bid
    {
        get { return _Bid; }
        set
        {
             If (_Bid < value)//, change fore color
                  ChangeColor = True;
            _Bid = value;
            DisplayCurrentPrice = String.Format("{0} / {1}", value, Ask);
    
        }
    }
    

    然后在 xaml 中

           <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="Height" Value="26" />
                    <Style.Triggers>
                       <DataTrigger Binding="{Binding Path=ChangeColor}" Value="True">
                          <Setter Property="ForeColor" Value="Red"/>
                       </DataTrigger >
                    </Style.Triggers>
                </Style>
            </ListView.ItemContainerStyle>
    

    【讨论】:

      猜你喜欢
      • 2013-09-03
      • 2016-05-09
      • 2011-04-23
      • 1970-01-01
      • 2012-02-03
      • 2011-11-25
      相关资源
      最近更新 更多