2016-09-27 47 views
0

我目前使用C#WPF DataGrid
DataGrid正在使用我的数据库作为ItemsSource,我使用DataGrid列出我的订单。
例如:如何根据单元格中的变量值设置数据网格行的背景

BIG BURGER 1
BIG MAC 1
干酪汉堡包1

麦乐2
鸡2
COCA-COLA 2
PEPSI 2

如你可以看到我从每个订单列出项目,并且每个项目旁边都有数字1或数字2.这些数字,正在帮助我定位哪个项目属于哪个订单。

我的问题是,如何绘制每行,哪些项目属于特定订单,例如,当项目与订单1关联时为红色,当项目与订单2关联时为蓝色等等。或者,作为替代方法,只绘制每个订单的最后一行(请参阅下面的粗体部分)。

我需要以某种方式将它们分开,因为当我将它们加载到datagrid时,它看起来很乱。

想象一下:

BIG BURGER 1 BIG MAC 1
干酪汉堡包1
麦乐2
鸡2
COCA-COLA 2
PEPSI 2
BIG BURGER 3
BIG MAC 3
干酪汉堡包3
麦乐3
鸡4
COCA-COLA 4
PEPSI 4

它看起来相当混乱..

(正如我前面所说的,只能在每个订单的最后一行绘制,只是为了在屏幕上创建可见的分隔,如果整行不可行。)

这是我到现在为止,但是这并不是最佳选择,因为它使用硬编码值:

<DataGrid.RowStyle> 
     <Style TargetType="DataGridRow"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding NumberOfOrder}" Value="1"> 
        <Setter Property="Background" Value="Red"></Setter> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding NumberOfOrder}" Value="2"> 
        <Setter Property="Background" Value="Green"></Setter> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding NumberOfOrder}" Value="3"> 
        <Setter Property="Background" Value="Orange"></Setter> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
</DataGrid.RowStyle> 

后面的代码:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     try 
     { 
      InitializeComponent(); 
      this.WindowStartupLocation = WindowStartupLocation.CenterScreen; 
      this.WindowState = WindowState.Maximized; 

      datagrid1.ItemsSource = OrdersController.localOrders(); 
     } 
     catch(Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
    } 
} 

在这里,你可以看到我使用硬编码值,如果我的​​是1,2或3 下一步:油漆行,这不是很好的解决方案,因为我将有许多不同的值NumberOfOrder

编辑时,垫的回答是:

public MainWindow() 
{ 
InitializeComponent(); 

    CollectionViewSource collectionViewSource = new CollectionViewSource(); 

    var ordersList = OrdersController.localOrders(); //ORDERS LIST 

    collectionViewSource.Source = new List<OrdersController.OrdersLocal>() 
    { 
     foreach(var item in ordersList) 
     { 
      new OrdersController.OrdersLocal() {Title = item.Title, NumberOfOrder = item.NumberOfOrder, Desc = item.Desc, User = item.User } 
     } 

    }; 

    collectionViewSource.GroupDescriptions.Add(new PropertyGroupDescription("NumberOfOrder")); 

    DataContext = collectionViewSource; 
} 
+0

.. ..Anyone? :( –

+0

啊现在我明白了;-)你可以做得更简单:collectionViewSource.Source = ordersList;或者如果你想使用OrdersLocal类,你可以到一个LINQ查询:collectionViewSource.Source = ordersList.Select(x => new OrdersLocal(){Title = x.Title}); – Mat

+0

感谢兄弟,这是真棒,顺便说一句,有可能把一些文本(如每个组的标题文本),当我崩溃的顺序,所以正在使用应用程序的人可以看到它即使订单被折叠。例如我点击折叠,但我想看到这样的文本Order:numberofOrder,所以我可以定位我倒塌的顺序:) –

回答

1

您可以通过NumberOfOrder使用CollectionViewSource和组: XAML:

 <DataGrid ItemsSource="{Binding}" > 
     <DataGrid.GroupStyle> 
      <!-- Style for groups at top level. --> 
      <GroupStyle> 
       <GroupStyle.ContainerStyle> 
        <Style TargetType="{x:Type GroupItem}"> 
         <Setter Property="Template"> 
          <Setter.Value> 
           <ControlTemplate TargetType="{x:Type GroupItem}"> 
            <Expander IsExpanded="True"> 
             <Expander.Header> 
              <DockPanel> 
               <TextBlock FontWeight="Bold" 
                  Text="{Binding Path=Name}" /> 
              </DockPanel> 
             </Expander.Header> 
             <Expander.Content> 
              <ItemsPresenter /> 
             </Expander.Content> 
            </Expander> 
           </ControlTemplate> 
          </Setter.Value> 
         </Setter> 
        </Style> 
       </GroupStyle.ContainerStyle> 
      </GroupStyle> 
     </DataGrid.GroupStyle> 
    </DataGrid> 

代码隐藏:

CollectionViewSource collectionViewSource = new CollectionViewSource(); 
     collectionViewSource.Source = new List<RowItem>() 
      { 
       new RowItem() {NumberOfOrder =1, Name ="kong foo" }, 
       new RowItem() {NumberOfOrder =1,Name ="asdf" }, 
       new RowItem() {NumberOfOrder =2,Name ="asdf" }, 
       new RowItem() {NumberOfOrder =3,Name ="foo"} 
      }; 


     collectionViewSource.GroupDescriptions.Add(new PropertyGroupDescription("NumberOfOrder")); 

     DataContext = collectionViewSource; 
+0

深入阅读:https://msdn.microsoft.com/en-us/library/ff407126(v=vs.110).aspx – Mat

+0

垫,你coment是如此有用!很快我会发布我的代码,我仍然有麻烦,但我会尽力解决这个问题! –

+0

Mat,我怎么能在这里应用foreach循环,在你的例子中,你向我展示了如何用4个对象解决这个问题,但想象我在数据库中有很多对象,我怎么能在这里循环每个对象并将它添加为新的RowItem ,我尝试了allready,但我有错误,说:“INVALID INITIALIZER ...” –

0

使用MultiDataTrigger改变顺序根据后台)订单号和b)最后一行。您可能想要在模型中添加一个属性,指出该行是否为该订单的最后一行。

尝试这样的事情(未经测试):

<Style.Triggers> 
    <MultiDataTrigger> 
     <MultiDataTrigger.Conditions> 
      <Condition Binding="{Binding NumberOfOrder}" Value="1" /> 
      <Condition Binding="{Binding IsLastRow}" Value="True" /> 
     </MultiDataTrigger.Conditions> 
     <Setter Property="Background" Value="Red" /> 
    </MultiDataTrigger> 
    ... 
</Style.Triggers>     
+0

不,它不是这样工作的:/,当我在同一时间加载5个命令时会发生什么? IsLastRow应该识别每个订单的最后一行吗?并画它? –

+0

我以为这就是你想要的,每一个订单的最后一行是不同的。你想要什么?空行? – leetibbett

+0

我在问你,即使所有的订单都在同一时间(例如五个订单)出现,它是否应该识别每个订单的最后一行,该方法仍然可以识别哪一行是对方的最后一行并将其绘制? –

1

你可以尝试使用一个值转换器结合这样做。

我这样做是为了单元格样式:

<Style TargetType="DataGridCell"> 
    <Setter Property="Background" 
      Value="{Binding State, Converter={x:Static l:Converters.CoupleStateConverter}}" /> 
        </Style> 

所以取决于状态(在我的例子INT)转换器返回的背景颜色。这与您的需求类似。

如您所见,单元格的数据上下文是行的值,所以我可以在我的示例中绑定到属性状态。我假设这一行对此有效,因此数据上下文将成为该行中显示的项目。

相关问题