DataGrid i liczenie wierszy.

0

Cześć,
Chciałem zapytać czy jest możliwość liczenia wierszy w DataGrid na podstawie warunku.
Chodzi mi mniej więcej o takie coś.
Mam DataGrida

<DataGrid x:Name="DBGrid">
               

                <DataGrid.Columns>
                    <DataGridTextColumn Header="ID" Binding="{Binding id}"/>
                    <DataGridTextColumn Header="Klient" Binding="{Binding getCustomerName}"/>
                    <DataGridTextColumn Header="Status" Binding="{Binding getStatus}" />                    
                </DataGrid.Columns>          
</DataGrid>            
<StatusBar VerticalAlignment="Bottom" Margin="5" >
            <StatusBarItem>
                <Label Content="Liczba wierszy:"/>
            </StatusBarItem>
            <StatusBarItem>
                <Label x:Name="lbAllRow" Content="{Binding ElementName=DBGrid, Path=Items.Count}"  /> 
            </StatusBarItem>
            <StatusBarItem>
            <Label Content="Liczba wierszy posiadających status 1:"/>
            </StatusBarItem>
            <StatusBarItem>
                <Label x:Name="lbStatusRow" Content="{Binding ElementName=DBGrid, Path=?????????????}"  />
            </StatusBarItem>
            <StatusBarItem>
                <Separator></Separator>
            </StatusBarItem>
</StatusBar>

W jaki sposób mogę przefiltorwać Items aby otrzymać nie ilość wszystkich wierszy ale np. ilość wierszy które mają określony status np. 2 ( w moim przypadku status to int)
Czy da się to zrobić w xaml czy muszę robić to w kodzie ?
Jak widać w belce bez problemu wyświetlę całkowitą ilość wierszy.
Pozdrawiam

0

W xaml można bez problemu odwoływać się do właściwości, dlatego bez problemu działa Count.
Aby przefiltrować listę musisz użyć w kodzie intereface ICollectionView i napisać metodę filtrującą i przypisac ją do Filter
Wtedy też odwołując się do przefiltrowanej listy poprzez Count otrzymasz ilość po przefiltrowaniu.

Chyba że potrzebujesz jednocześnie informacji ile jest czego to wtedy pozostaje bindować właściwość, która za pomocą LINQ liczysz to co chcesz i przypisujesz ilość do tej konkretnej właściwości.

2

Nade wszystko chwalebne jest odczytywanie z Modelu, a nie z widgetu GUI.
@Piotr.Net: pośrednio chyba to chciał zasugerować, ale (jak myślę) nie dopowiedział do końca.

0

@ZrobieDobrze: w tym przypadku najpoprawniej będzie dodać wiązanie do właściwości count i napisanie niestandardowego konwertera.
Bindujesz do count
Gdy count się zmieni zamiast wyświetlać count używasz konwertera podając jako argument elementy z listy.
Używasz count włączając warunek i zwracasz nową wartość

0

@gswidwa1: Spróbuję tak zrobić, choć muszę na ten temat jeszcze poczytać bo jest to dla mnie nowe i nigdy jeszcze nie tworzyłem konwertera.

0

@gswidwa1: Mam pytanie bo nie do końca to rozumiem. Stworzyłem sobie converter.

internal class status2 : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
           
            ......................
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

w xaml mam wpis

             <StatusBarItem>
                <Label Content="Liczba statusów 2:"/>
            </StatusBarItem>
            <StatusBarItem>
                <Label x:Name="lbStatus2" Content="{Binding ElementName=DBGrid, Path=Items.count, Converter={StaticResource status2}}" />
            </StatusBarItem>

I teraz mam pytanie.
Przesyłając do konwertera Items.count przesyłam całą liczbę wierszy, która jest wartością int. Z tego co zrozumiałem musiałbym do konwertera przesłać cały rekord na podstawie którego mógłbym zliczyć pola status z wartością 2 (nie wiem czy dobrze myślę). Czy mógłbyś mi podpowiedzieć co dokładnie muszę przesłać do konwertera? (samo Items). Bo wydaje mi się że count to mi nic nie da. Chyba, że coś poknociłem.
Pozdrawiam

0

@Blacha: jako wartość Parameter (Nie pamiętam, czy da się użyć do tego bindingu).
https://riptutorial.com/wpf/example/13771/usage-converters-with-converterparameter
Jeżeli nie, to trzeba użyć MultiValueConverter.
https://www.c-sharpcorner.com/UploadFile/87b416/wpf-multivalue-converters/
Tak czy siak, musisz podać odwołanie do swojej listy obiektów do konwertera. Następnie wykonujesz kwerendę i załatwione.

Tak to powinno działąć. Wtedy masz porządek w swoim ViewModelu
ViewModel i konwerter:

public class MainWindowViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public MainWindowViewModel()
        {
            MyList = new ObservableCollection<string>();
            MyList.Add("614187246981264819462");
            MyList.Add("rc82tg97 n347gt978bv3284g");
            MyList.Add("3y5b2y45uy24n574");
            MyList.Add("2b465u245vy246u356n8u23b45uy2457u2");
            MyList.Add("2b45u245bu");
            MyList.Add("2b465u2546nu24b57u245uyb245uyb245u245u245u");
            MyList.Add("vh245bh245h");
            MyList.Add("2b465un52by54cy354yvv45y");
            MyList.Add("2v45y25yv");
            MyList.Add("2v45uy425");
            MyList.Add("2v456u2yv25y245y2v45y245y245vy245y245y");
            MyList.Add("245vy245");
        }

        public IList<string> MyList { get; set; }
    }
    public class NumberOfRecordsWithMinimalStringLength : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            int count = (int)values[0];
            IList<string> myList = (IList<string>)values[1];
            return myList.Count(x => x.Count() > 20).ToString();
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

XAML

<Window x:Class="WpfApp1.MainWindow"
        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:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <local:NumberOfRecordsWithMinimalStringLength x:Key="MyConverter"/>
    </Window.Resources>
    <Grid>
        <Grid.DataContext>
            <local:MainWindowViewModel x:Name="hViewModel"/>
        </Grid.DataContext>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0">
            <GroupBox Header="Liczba elementów które mają więcej niż 20 znaków:" BorderThickness="2" BorderBrush="Black">
                <TextBlock>
                    <TextBlock.Text>
                        <MultiBinding Converter="{StaticResource MyConverter}">
                            <MultiBinding.Bindings>
                                <Binding Path="MyList.Count"/>
                                <Binding Path="MyList"/>
                            </MultiBinding.Bindings>
                        </MultiBinding>
                    </TextBlock.Text>
                </TextBlock>
            </GroupBox>
        </StackPanel>
        <ListBox Grid.Row="1" ItemsSource="{Binding Path=MyList}">
            
        </ListBox>
    </Grid>
</Window>

screenshot-20220422001259.png

1 użytkowników online, w tym zalogowanych: 0, gości: 1