Hallo
Ich hätte mal eine Frage und zwar möchte ich wenn ich im DataGrid ein Datensatz auswähle, sofort eine DB Abfrage läuft.
Bis jetzt geht das nur über InputBindings. Da muss ich aber zwei mal klicken und das finde ich doof. Ich weiß das ist bistimmt eine einfache Sache aber ich komme nicht drauf.
<DataGrid
x:Name="dataGrid"
materialDesign:DataGridAssist.CellPadding="5"
materialDesign:DataGridAssist.ColumnHeaderPadding="3"
ItemsSource="{Binding FilterCollection}"
AutoGenerateColumns="False"
CanUserAddRows="False"
Background="White"
FontSize="16"
IsReadOnly="True"
ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
SelectionMode="Single"
SelectionUnit="FullRow" AlternationCount="2">
<DataGrid.InputBindings>
<MouseBinding
MouseAction="LeftClick"
Command="{Binding IsSelectClickCommand}"
CommandParameter="{Binding ElementName=dataGrid, Path=SelectedItem}"/>
</DataGrid.InputBindings>
<DataGrid.Resources>
<Style TargetType="DataGridRow">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="Green" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
Model
public KwEvaluationWindowModel()
{
this.CheckBoxClickCommand = new DelegateCommand
(
(o) => PlatformKw != null,
(o) => { CheckBoxCommand(o); }
);
this.ExportClickCommand = new DelegateCommand
(
(o) => PlatformKw != null,
(o) => { ExportCommand(PlatformKw); }
);
this.IsSelectClickCommand = new DelegateCommand
(
(o) => PlatformKw != null,
(o) => { IsSelectCommand(o); }
);
this.CloseClickCommand = new DelegateCommand
(
(o) => PlatformKw != null,
(o) => { CloseCommand(o); }
);
}
private void IsSelectCommand(object o)
{
var selectedRow = o as AmazonKwEvaluationList;
VkArtikel = (selectedRow.week_cur + selectedRow.week_a + selectedRow.week_b + selectedRow.week_c + selectedRow.week_d + selectedRow.week_e + selectedRow.week_f + selectedRow.week_g + selectedRow.week_h + selectedRow.week_i + selectedRow.week_j + selectedRow.week_k + selectedRow.week_l + selectedRow.week_m + selectedRow.week_n + selectedRow.week_o + selectedRow.week_p + selectedRow.week_q + selectedRow.week_r + selectedRow.week_s + selectedRow.week_t + selectedRow.week_u + selectedRow.week_v + selectedRow.week_w + selectedRow.week_x + selectedRow.week_y + selectedRow.week_z
+ selectedRow.week_aa + selectedRow.week_ab + selectedRow.week_ac + selectedRow.week_ad + selectedRow.week_ae + selectedRow.week_af + selectedRow.week_ag + selectedRow.week_ah + selectedRow.week_ai + selectedRow.week_aj + selectedRow.week_ak + selectedRow.week_al + selectedRow.week_am + selectedRow.week_an + selectedRow.week_ao + selectedRow.week_ap + selectedRow.week_aq + selectedRow.week_ar + selectedRow.week_as + selectedRow.week_at + selectedRow.week_au + selectedRow.week_av + selectedRow.week_aw + selectedRow.week_ax + selectedRow.week_ay).ToString() + " St.";
UmArtikel = (selectedRow.price_cur + selectedRow.price_a + selectedRow.price_b + selectedRow.price_c + selectedRow.price_d + selectedRow.price_e + selectedRow.price_f + selectedRow.price_g + selectedRow.price_h + selectedRow.price_i + selectedRow.price_j + selectedRow.price_k + selectedRow.price_l + selectedRow.price_m + selectedRow.price_n + selectedRow.price_o + selectedRow.price_p + selectedRow.price_q + selectedRow.price_r + selectedRow.price_s + selectedRow.price_t + selectedRow.price_u + selectedRow.price_v + selectedRow.price_w + selectedRow.price_x + selectedRow.price_y + selectedRow.price_z
+ selectedRow.price_aa + selectedRow.price_ab + selectedRow.price_ac + selectedRow.price_ad + selectedRow.price_ae + selectedRow.price_af + selectedRow.price_ag + selectedRow.price_ah + selectedRow.price_ai + selectedRow.price_aj + selectedRow.price_ak + selectedRow.price_al + selectedRow.price_am + selectedRow.price_an + selectedRow.price_ao + selectedRow.price_ap + selectedRow.price_aq + selectedRow.price_ar + selectedRow.price_as + selectedRow.price_at + selectedRow.price_au + selectedRow.price_av + selectedRow.price_aw + selectedRow.price_ax + selectedRow.price_ay).ToString("#,#.00", CultureInfo.InvariantCulture) + " €";
MaArtikel = (selectedRow.margin_cur + selectedRow.margin_a + selectedRow.margin_b + selectedRow.margin_c + selectedRow.margin_d + selectedRow.margin_e + selectedRow.margin_f + selectedRow.margin_g + selectedRow.margin_h + selectedRow.margin_i + selectedRow.margin_j + selectedRow.margin_k + selectedRow.margin_l + selectedRow.margin_m + selectedRow.margin_n + selectedRow.margin_o + selectedRow.margin_p + selectedRow.margin_q + selectedRow.margin_r + selectedRow.margin_s + selectedRow.margin_t + selectedRow.margin_u + selectedRow.margin_v + selectedRow.margin_w + selectedRow.margin_x + selectedRow.margin_y + selectedRow.margin_z
+ selectedRow.margin_aa + selectedRow.margin_ab + selectedRow.margin_ac + selectedRow.margin_ad + selectedRow.margin_ae + selectedRow.margin_af + selectedRow.margin_ag + selectedRow.margin_ah + selectedRow.margin_ai + selectedRow.margin_aj + selectedRow.margin_ak + selectedRow.margin_al + selectedRow.margin_am + selectedRow.margin_an + selectedRow.margin_ao + selectedRow.margin_ap + selectedRow.margin_aq + selectedRow.margin_ar + selectedRow.margin_as + selectedRow.margin_at + selectedRow.margin_au + selectedRow.margin_av + selectedRow.margin_aw + selectedRow.margin_ax + selectedRow.margin_ay).ToString("#,#.00", CultureInfo.InvariantCulture) + " €";
QuarterArticle = listPreparationRepository.GetQuarterArticle(selectedRow.Article, selectedRow.Platform, DateTime.Now.Year.ToString());
}
Hierfür gibt es bestimmt eine schönere Methode.
Danke schon mal.
Kannst du nicht direkt an SelectedItem binden und in dessen Setter IsSelectCommand(value)
aufrufen?
Edit: Was ist denn das für ein Datenmodell, wo du Eigenschaften week_a
...week_z
,price_a
... price_z
, margin_a
...margin_z
(bzw. ..._aa
- ..._ay
) hast?
Hi
Doch habe ich auch versucht aber funktioniert nicht.
<DataGrid
x:Name="dataGrid"
materialDesign:DataGridAssist.CellPadding="5"
materialDesign:DataGridAssist.ColumnHeaderPadding="3"
ItemsSource="{Binding FilterCollection}"
AutoGenerateColumns="False"
CanUserAddRows="False"
Background="White"
FontSize="16"
IsReadOnly="True"
ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Visible"
ScrollViewer.VerticalScrollBarVisibility="Visible"
SelectedItem="{Binding MySelectedItem}"
SelectionMode="Single"
SelectionUnit="FullRow" AlternationCount="2">
<DataGrid.Resources>
<Style TargetType="DataGridRow">
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="BorderBrush" Value="Green" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.Resources>
Model
private QuarterList mySelectedItem;
public QuarterList MySelectedItem
{
get => this.mySelectedItem;
set
{
if (this.mySelectedItem != value)
{
this.mySelectedItem = value;
}
}
}
Der Geter wird beim Select nicht angesprochen. Irgendwas stimmt da nicht. Bloß was. Wenn das gehen würde, würde ich dann von dort IsSelectCommand aufrufen.
Das Datenmodul ist eine Liste von Verkäufe nach KW, Umsatz und Marge.
Sorry habe jetzt den Fehler gefunden das war die Falsche Klasse. Nicht QuarterList sondern AmazonKwEvaluationList.
Ich hätte trotzdem nochmal eine Frage und zwar Radio Button Binding.
In den Bild unten darf nur jeweils ein RadioButton markiert werden.
<Grid Grid.Column="0">
<GroupBox
Name="GroupBoxPlatformDetailText"
Padding="4"
Header="Plattform" Margin="10,0,0,0">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Orientation="Vertical" Margin="0,0,0,0">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left" >
<RadioButton x:Name="amazonCheck" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="Amazon" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=amazonCheck}" Width="120" />
<RadioButton x:Name="ottoCheck" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="Otto" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=ottoCheck}" />
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0">
<RadioButton x:Name="amazonDeCheck" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="Amazon.de" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=amazonDeCheck}" Width="120" />
<RadioButton x:Name="kauflandCheck" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="Kaufland" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=kauflandCheck}" />
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0">
<RadioButton x:Name="amazonUkCheck" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="Amazon.uk" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=amazonUkCheck}" Width="120" />
<RadioButton x:Name="vendorCheck" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="Amazon Vendor" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=vendorCheck}" />
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0">
<RadioButton x:Name="amazonFrCheck" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="Amazon.fr" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=amazonFrCheck}" Width="120" />
<RadioButton x:Name="digitecCheckCH" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="Digitec Galaxus" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=digitecCheckCH}" />
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0">
<RadioButton x:Name="amazonEsCheck" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="Amazon.es" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=amazonEsCheck}" Width="120" />
<RadioButton x:Name="digitecCheckDE" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="Digitec DE" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=digitecCheckDE}" IsEnabled="False" />
</StackPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="0,0,0,0">
<RadioButton x:Name="amazonItCheck" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="Amazon.it" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=amazonItCheck}" Width="120" />
<RadioButton x:Name="ebayCheck" IsChecked="{Binding IsChecked, Mode=TwoWay}" Content="eBay" Command="{Binding CheckBoxClickCommand}" CommandParameter="{Binding Content, ElementName=ebayCheck}" />
</StackPanel>
</StackPanel>
</GroupBox>
</Grid>
Model
private bool _IsChecked;
public bool IsChecked
{
get => _IsChecked;
set
{
if (_IsChecked != value)
{
_IsChecked = value;
this.RaisePropertyChanged();
}
}
}
Die Daten werden angezeigt wie ich es möchte aber wenn eine Plattform ausgewählt wurde ist der nicht IsCheck true. Wenn ich den Mode=TwoWay raus nehme sind alle true. Wenn der Mode angegeben ist werden die nur kurz markiert. Wie macht man das richtig in MVVM ?
Schau dir die GroupName Property an.
Jo danke, ist ja einfach 😃
Eine letzte Frage hätte ich aber noch. Mein Visibility Binding Funktioniert nicht. Der soll den Spinner auslössen.
<Border
Name="OverlayDataGrid"
Grid.Row="0"
Grid.RowSpan="5"
Panel.ZIndex="1"
Background="LightGray"
Opacity="0.7"
Visibility="{Binding VisibilityBorder, Converter={StaticResource booleanVisibilityConverter}}">
<fa5:ImageAwesome
Name="OverlayDataGridSpinner"
Width="128"
Height="128"
Icon="Solid_Robot"
Spin="{Binding Spin}"
SpinDuration="15"/>
</Border>
Model
private bool _visibilityBorder = false;
public bool VisibilityBorder
{
get => _visibilityBorder;
set
{
if (_visibilityBorder != value)
{
_visibilityBorder = value;
this.RaisePropertyChanged();
}
}
}
private bool _spin;
public bool Spin
{
get => _spin;
set
{
if (_spin != value)
{
_spin = value;
this.RaisePropertyChanged();
}
}
}
private void CheckBoxCommand(object o)
{
VisibilityBorder = true;
Spin = true;
platform = o as string;
marketplace = "";
QuarterArticle = null;
if (platform.Contains('.'))
{
marketplace = platform;
platform = "";
}
PlatformKw = listPreparationRepository.GetVendorAmazonDataKW(platform, marketplace);
Quarter = listPreparationRepository.GetQuarter(platform, marketplace, DateTime.Now.Year.ToString());
FilterCollection = CollectionViewSource.GetDefaultView(PlatformKw);
//HeaderGroupBox = "Artikel (" + PlatformKw.Count.ToString() + ")";
GetHeaderGroupBoxCount();
Spin = false;
VisibilityBorder = false;
}
Converter
public class BoolToVisConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
if ((bool)value)
{
return Visibility.Visible;
}
else
{
return Visibility.Collapsed;
}
}
catch
{
return Visibility.Collapsed;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
if ((bool)value)
{
return Visibility.Visible;
}
}
catch { }
return Visibility.Collapsed;
}
}
Wenn der VisibilityBorder auf true gesetzt wird gibt es keine reaxtion. Der Converter wird aber angesprochen.
Wenn ich den VisibilityBorder statt auf false auf true setze, funktioniert es nach der Abfrage.
Wo könnte hier das Problem liegen ???
Beim BoolToVisConverter
ist eine der beiden Methoden falsch implementiert (ich denke ConvertBack
), denn es muß ja einmal von bool
nach Visibility
konvertiert werden und in der anderen Methode genau umgekehrt.
Und beim Datenmodell meine ich: warum hast du dort kein Array (bzw. List<...>
), anstatt den zig Einzeleigenschaften?
Außerdem sollte die Klasse AmazonKwEvaluationList
besser ...Entry
oder ...Row
heißen (denn es handelt sich ja um einen einzigen Datensatz, keine Liste).
Ich habe jetzt einiges hin und her probiert aber ich bekomme den Converter nicht zum laufen ???
Beim debug merke ich auch das der ConvertBack, nicht angesprochen wird.
private void CheckBoxCommand(object o)
{
VisibilityBorder = true;
Spin = true;
platform = o as string;
marketplace = "";
QuarterArticle = null;
if (platform.Contains('.'))
{
marketplace = platform;
platform = "";
}
PlatformKw = listPreparationRepository.GetVendorAmazonDataKW(platform, marketplace);
Quarter = listPreparationRepository.GetQuarter(platform, marketplace, DateTime.Now.Year.ToString());
FilterCollection = CollectionViewSource.GetDefaultView(PlatformKw);
//HeaderGroupBox = "Artikel (" + PlatformKw.Count.ToString() + ")";
GetHeaderGroupBoxCount();
Spin = true;
VisibilityBorder = true;
};
Wenn ich den teil zwei mal auf true setze geht es aber dann ist die Abfrage schon durch.
Spin = false;
VisibilityBorder = false;
Was genau meinst du mit dem Satz ?
Und beim Datenmodell meine ich: warum hast du dort kein Array (bzw. List<...>), anstatt den zig Einzeleigenschaften?
Du meinst das. Das ist ein Datensatz einer Liste.
VkArtikel = (selectedRow.week_cur + selectedRow.week_a + selectedRow.week_b + selectedRow.week_c + selectedRow.week_d + selectedRow.week_e + selectedRow.week_f + selectedRow.week_g + selectedRow.week_h + selectedRow.week_i + selectedRow.week_j + selectedRow.week_k + selectedRow.week_l + selectedRow.week_m + selectedRow.week_n + selectedRow.week_o + selectedRow.week_p + selectedRow.week_q + selectedRow.week_r + selectedRow.week_s + selectedRow.week_t + selectedRow.week_u + selectedRow.week_v + selectedRow.week_w + selectedRow.week_x + selectedRow.week_y + selectedRow.week_z
+ selectedRow.week_aa + selectedRow.week_ab + selectedRow.week_ac + selectedRow.week_ad + selectedRow.week_ae + selectedRow.week_af + selectedRow.week_ag + selectedRow.week_ah + selectedRow.week_ai + selectedRow.week_aj + selectedRow.week_ak + selectedRow.week_al + selectedRow.week_am + selectedRow.week_an + selectedRow.week_ao + selectedRow.week_ap + selectedRow.week_aq + selectedRow.week_ar + selectedRow.week_as + selectedRow.week_at + selectedRow.week_au + selectedRow.week_av + selectedRow.week_aw + selectedRow.week_ax + selectedRow.week_ay).ToString() + " St.";
UmArtikel = (selectedRow.price_cur + selectedRow.price_a + selectedRow.price_b + selectedRow.price_c + selectedRow.price_d + selectedRow.price_e + selectedRow.price_f + selectedRow.price_g + selectedRow.price_h + selectedRow.price_i + selectedRow.price_j + selectedRow.price_k + selectedRow.price_l + selectedRow.price_m + selectedRow.price_n + selectedRow.price_o + selectedRow.price_p + selectedRow.price_q + selectedRow.price_r + selectedRow.price_s + selectedRow.price_t + selectedRow.price_u + selectedRow.price_v + selectedRow.price_w + selectedRow.price_x + selectedRow.price_y + selectedRow.price_z
+ selectedRow.price_aa + selectedRow.price_ab + selectedRow.price_ac + selectedRow.price_ad + selectedRow.price_ae + selectedRow.price_af + selectedRow.price_ag + selectedRow.price_ah + selectedRow.price_ai + selectedRow.price_aj + selectedRow.price_ak + selectedRow.price_al + selectedRow.price_am + selectedRow.price_an + selectedRow.price_ao + selectedRow.price_ap + selectedRow.price_aq + selectedRow.price_ar + selectedRow.price_as + selectedRow.price_at + selectedRow.price_au + selectedRow.price_av + selectedRow.price_aw + selectedRow.price_ax + selectedRow.price_ay).ToString("#,#.00", CultureInfo.InvariantCulture) + " €";
MaArtikel = (selectedRow.margin_cur + selectedRow.margin_a + selectedRow.margin_b + selectedRow.margin_c + selectedRow.margin_d + selectedRow.margin_e + selectedRow.margin_f + selectedRow.margin_g + selectedRow.margin_h + selectedRow.margin_i + selectedRow.margin_j + selectedRow.margin_k + selectedRow.margin_l + selectedRow.margin_m + selectedRow.margin_n + selectedRow.margin_o + selectedRow.margin_p + selectedRow.margin_q + selectedRow.margin_r + selectedRow.margin_s + selectedRow.margin_t + selectedRow.margin_u + selectedRow.margin_v + selectedRow.margin_w + selectedRow.margin_x + selectedRow.margin_y + selectedRow.margin_z
+ selectedRow.margin_aa + selectedRow.margin_ab + selectedRow.margin_ac + selectedRow.margin_ad + selectedRow.margin_ae + selectedRow.margin_af + selectedRow.margin_ag + selectedRow.margin_ah + selectedRow.margin_ai + selectedRow.margin_aj + selectedRow.margin_ak + selectedRow.margin_al + selectedRow.margin_am + selectedRow.margin_an + selectedRow.margin_ao + selectedRow.margin_ap + selectedRow.margin_aq + selectedRow.margin_ar + selectedRow.margin_as + selectedRow.margin_at + selectedRow.margin_au + selectedRow.margin_av + selectedRow.margin_aw + selectedRow.margin_ax + selectedRow.margin_ay).ToString("#,#.00", CultureInfo.InvariantCulture) + " €";
Jetzt verstehe ich, was du mit VisibilityBorder
und Spin
erreichen möchtest - du möchtest diese temporär ausblenden, während der Datenbank-Abfrage. So funktioniert das aber nicht, da die Änderungen erst erfolgen, wenn die gesamte Methode abgearbeitet ist (und die Windows- bzw. WPF-Nachrichtenschleife wieder ein Update der UI anstößt - s.a. [FAQ] Warum blockiert mein GUI?).
Hierfür benötigst du dann asynchrone Programmierung (async
/ await
/ Task<T>
), um auf die Datenbankabfrage zu warten.
Und bei deinem Datensatz ist immer noch die Frage, warum hast du soviele einzelne Eigenschaften? Ist diese Klasse AmazonKwEvaluationList
(der Variablen selectedRow
) automatisch generiert (erinnert mich von der Benennung an Excel-Spalten)?
Einfacher wäre doch jeweils ein Array Weeks[index]
, Prices[index]
, ... (und dann eine Schleife, um die Summe zu ermitteln).
Converter
public class BoolToVisConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
var boolValue = (bool)value;
if (boolValue)
return Visibility.Visible;
else
return Visibility.Collapsed;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
if (((Visibility)value).Equals(Visibility.Collapsed))
return false;
else
return true;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
Ahhhh Danke alles klar, das weiß ich ja auch eigentlich. Ändere ich jetzt.
Deinen zweiten vorschlag werde ich mir nächte Woche zur brust nehmen. Danke
So Funktioniert jetzt, danke nochmal.
private async void IsSelectCommand(object o)
{
var selectedRow = o as AmazonKwEvaluationList;
if (selectedRow != null)
{
VisibilityBorder = true;
Spin = true;
someTask = Task.Run(new Action(async () =>
{
VkArtikel = (selectedRow.week_cur + selectedRow.week_a + selectedRow.week_b + selectedRow.week_c + selectedRow.week_d + selectedRow.week_e + selectedRow.week_f + selectedRow.week_g + selectedRow.week_h + selectedRow.week_i + selectedRow.week_j + selectedRow.week_k + selectedRow.week_l + selectedRow.week_m + selectedRow.week_n + selectedRow.week_o + selectedRow.week_p + selectedRow.week_q + selectedRow.week_r + selectedRow.week_s + selectedRow.week_t + selectedRow.week_u + selectedRow.week_v + selectedRow.week_w + selectedRow.week_x + selectedRow.week_y + selectedRow.week_z
+ selectedRow.week_aa + selectedRow.week_ab + selectedRow.week_ac + selectedRow.week_ad + selectedRow.week_ae + selectedRow.week_af + selectedRow.week_ag + selectedRow.week_ah + selectedRow.week_ai + selectedRow.week_aj + selectedRow.week_ak + selectedRow.week_al + selectedRow.week_am + selectedRow.week_an + selectedRow.week_ao + selectedRow.week_ap + selectedRow.week_aq + selectedRow.week_ar + selectedRow.week_as + selectedRow.week_at + selectedRow.week_au + selectedRow.week_av + selectedRow.week_aw + selectedRow.week_ax + selectedRow.week_ay).ToString() + " St.";
UmArtikel = (selectedRow.price_cur + selectedRow.price_a + selectedRow.price_b + selectedRow.price_c + selectedRow.price_d + selectedRow.price_e + selectedRow.price_f + selectedRow.price_g + selectedRow.price_h + selectedRow.price_i + selectedRow.price_j + selectedRow.price_k + selectedRow.price_l + selectedRow.price_m + selectedRow.price_n + selectedRow.price_o + selectedRow.price_p + selectedRow.price_q + selectedRow.price_r + selectedRow.price_s + selectedRow.price_t + selectedRow.price_u + selectedRow.price_v + selectedRow.price_w + selectedRow.price_x + selectedRow.price_y + selectedRow.price_z
+ selectedRow.price_aa + selectedRow.price_ab + selectedRow.price_ac + selectedRow.price_ad + selectedRow.price_ae + selectedRow.price_af + selectedRow.price_ag + selectedRow.price_ah + selectedRow.price_ai + selectedRow.price_aj + selectedRow.price_ak + selectedRow.price_al + selectedRow.price_am + selectedRow.price_an + selectedRow.price_ao + selectedRow.price_ap + selectedRow.price_aq + selectedRow.price_ar + selectedRow.price_as + selectedRow.price_at + selectedRow.price_au + selectedRow.price_av + selectedRow.price_aw + selectedRow.price_ax + selectedRow.price_ay).ToString("#,#.00", CultureInfo.InvariantCulture) + " €";
MaArtikel = (selectedRow.margin_cur + selectedRow.margin_a + selectedRow.margin_b + selectedRow.margin_c + selectedRow.margin_d + selectedRow.margin_e + selectedRow.margin_f + selectedRow.margin_g + selectedRow.margin_h + selectedRow.margin_i + selectedRow.margin_j + selectedRow.margin_k + selectedRow.margin_l + selectedRow.margin_m + selectedRow.margin_n + selectedRow.margin_o + selectedRow.margin_p + selectedRow.margin_q + selectedRow.margin_r + selectedRow.margin_s + selectedRow.margin_t + selectedRow.margin_u + selectedRow.margin_v + selectedRow.margin_w + selectedRow.margin_x + selectedRow.margin_y + selectedRow.margin_z
+ selectedRow.margin_aa + selectedRow.margin_ab + selectedRow.margin_ac + selectedRow.margin_ad + selectedRow.margin_ae + selectedRow.margin_af + selectedRow.margin_ag + selectedRow.margin_ah + selectedRow.margin_ai + selectedRow.margin_aj + selectedRow.margin_ak + selectedRow.margin_al + selectedRow.margin_am + selectedRow.margin_an + selectedRow.margin_ao + selectedRow.margin_ap + selectedRow.margin_aq + selectedRow.margin_ar + selectedRow.margin_as + selectedRow.margin_at + selectedRow.margin_au + selectedRow.margin_av + selectedRow.margin_aw + selectedRow.margin_ax + selectedRow.margin_ay).ToString("#,#.00", CultureInfo.InvariantCulture) + " €";
QuarterArticle = await listPreparationRepository.GetQuarterArticle(selectedRow.Article, platform, marketplace, DateTime.Now.Year.ToString());
}));
await someTask;
VisibilityBorder = false;
Spin = false;
}
else
{
QuarterArticle = null;
VkArtikel = "";
UmArtikel = "";
MaArtikel = "";
}
}
Deine Frage bezüglich des Datensatz, verstehe ich jetzt nicht genau was du meinst ?
Das ist ja eine Klasse wo ich unterschiedliche Berechnungen durchführen muss. Du meinst es ist einfacher mit einem Array. Wie genau ?
Zitat von Th69
Und bei deinem Datensatz ist immer noch die Frage, warum hast du soviele einzelne Eigenschaften? Ist diese Klasse
AmazonKwEvaluationList
(der VariablenselectedRow
) automatisch generiert (erinnert mich von der Benennung an Excel-Spalten)?Einfacher wäre doch jeweils ein Array
Weeks[index]
,Prices[index]
, ... (und dann eine Schleife, um die Summe zu ermitteln).
Sorry, aber ich weiß nicht was ich noch mehr dazu schreiben soll. Du weißt doch sicherlich, wie man ein Array (oder List<...>
) anlegt?!
Wie füllst du denn diese Eigenschaften? Vllt. liegt ja da dein (bisheriger) Denkfehler?
Hi
Danke für alles.
Ich hätte da nochmal eine Frage. Ich möchte zusätzlich ein neues Windows öfnen. Wie würde das Funktionieren. Habe jetzt echt einiges ausprobiert mit Async etc...
Hat hier jemand eine Idee ??? Die Seite wird aufgerufen nur der Spinner Funktioniert so nicht.
Jetzt verstehe ich, was du mit VisibilityBorder und Spin erreichen möchtest - du möchtest diese temporär ausblenden, während der Datenbank-Abfrage. So funktioniert das aber nicht, da die Änderungen erst erfolgen, wenn die gesamte Methode abgearbeitet ist (und die Windows- bzw. WPF-Nachrichtenschleife wieder ein Update der UI anstößt - s.a. [FAQ] Warum blockiert mein GUI?).
Hierfür benötigst du dann asynchrone Programmierung (async/ await/ Task<T>), um auf die Datenbankabfrage zu warten.
Model
public MainWindowModel()
{
this.LoginCommand = new ViewModelCommand(ExecuteLoginCommand, CanExecuteLoginCommand);
Username = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
}
private bool CanExecuteLoginCommand(object obj)
{
bool validData;
if (string.IsNullOrWhiteSpace(Username) || Username.Length < 3 ||
Password == null || Password.Length < 3)
validData = false;
else
validData = true;
return validData;
}
private async void ExecuteLoginCommand(object obj)
{
// Set up the loading spinner on the UI thread
ShowLoadingSpinner();
// Show the new window asynchronously
await Application.Current.Dispatcher.InvokeAsync(() =>
{
var isValidUser = AuthenticateUser(new NetworkCredential(Username, Password));
if (isValidUser)
{
Thread.CurrentPrincipal = new GenericPrincipal(
new GenericIdentity(Username), null);
MainDispoView mainDispoView = new MainDispoView();
mainDispoView.Show();
Application.Current.MainWindow.Close();
}
else
{
ErrorMessage = "* Invalid username or password";
}
});
CloseLoadingSpinner();
}
private void CloseLoadingSpinner()
{
// Update UI elements related to the loading spinner using the Dispatcher
Application.Current.Dispatcher.Invoke(() =>
{
// Show loading spinner logic (e.g., set a property bound to visibility)
// You can define a property in your ViewModel to control the visibility of the spinner.
IsViewVisible = false;
IsLoading = false;
});
}
private void ShowLoadingSpinner()
{
// Update UI elements related to the loading spinner using the Dispatcher
Application.Current.Dispatcher.Invoke(() =>
{
// Close loading spinner logic (e.g., set a property bound to visibility)
IsLoading = true;
IsViewVisible = true;
});
}
Was für eine Authentifizierung soll das werden? Warum behandelst Du UserName und Password in der App?
Wenn Du gegen Microsoft Entra authentifizierst, dann solltest Du die den Public Client verwenden.
Wenn es sich um ein lokales Active Directory handelt, solltest Du ADFS verwenden. Habt ihr noch kein ADFS, was haarsträubend wäre, dann gibts immer noch WindowsIdentity.GetCurrent()
Aber gibt eigentlich kein Grund, außer ihr habt was proprietäres, dass Du Username und Password handlen musst. Ist schließlich ein Security Vector.
Wenn Du async/await korrekt implementierst, was hier nicht der Fall ist, dann brauchst Du das ganze Invoke-Zeug hier nicht mehr.
Der gesamte Inhalt von ExecuteLoginCommand
macht so kein Sinn; also selbst wenn Du das alles mit Invoke machen willst.
Da stimmt auch die gesamte Reihenfolge und Thread-Zugehörigen alles nicht mehr.
[FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) ganz unten.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code