gpt4 book ai didi

c# - 如何将不同的查询结果绑定(bind)到组合框并将其作为选定的单元格值传递

转载 作者:行者123 更新时间:2023-11-30 21:26:58 24 4
gpt4 key购买 nike

我已经尝试了很多 Stack Overflow 的答案,但我就是找不到一个简单的例子来说明我希望实现的目标。

我试图用来自表 (dimDate) 的不同结果填充组合框,并在选择网格行(来自安全表)时更改该组合框选择。

不用说,我一直在尝试的东西并没有按预期工作。我做错了什么,我怎样才能用最简单的工作示例解决这个问题?

MainWindow.xaml

<Label Content="Year" Margin="0,0,10,0" Grid.Row="0" Grid.Column="0"/>
<ComboBox x:Name="txtyr" Grid.Row="0" Grid.Column="0"
Width="115" SelectedIndex="0" DisplayMemberPath="Year"
ItemsSource="{Binding Years}"
SelectedValue="{Binding Path=years_SelectedValue}"
SelectedValuePath="value">
</ComboBox>

<Label Content="Quarter" Margin="0,0,10,0" Grid.Row="0" Grid.Column="1"/>
<ComboBox x:Name="txtqt" Grid.Row="0" Grid.Column="1"
Width="115" SelectedIndex="0" DisplayMemberPath="Year"
ItemsSource="{Binding Quarters}"
SelectedValue="{Binding Path=quarters_SelectedValue}"
SelectedValuePath="value"/>

<Label Content="Name" Margin="0,0,10,0" Grid.Row="0" Grid.Column="2"/>
<ComboBox x:Name="txtnm" Grid.Row="0" Grid.Column="2"
Width="115" SelectedIndex="0" DisplayMemberPath="Year"
ItemsSource="{Binding Names}"
SelectedValue="{Binding Path=names_SelectedValue}"
SelectedValuePath="value"/>

<Label Content="Safery Score:" Margin="0,0,10,0" Grid.Row="1" Grid.Column="0"/>
<Controls:NumericUpDown x:Name="txtssc" Grid.Row="2" Grid.Column="0"
Controls:TextBoxHelper.HasText="True" Width="115" Height="20"
Controls:TextBoxHelper.Watermark="Score"
UpDownButtonsWidth="25" Maximum="10" Minimum="-10" HasDecimals="False"
InterceptArrowKeys="True" InterceptMouseWheel="True"
/>

<DataGrid Grid.Row="1" Margin="10,10,0,0" AutoGenerateColumns="False" VirtualizingPanel.IsVirtualizingWhenGrouping="True" EnableColumnVirtualization="True" EnableRowVirtualization="True" VirtualizingPanel.IsVirtualizing="true" ColumnHeaderStyle="{StaticResource lowCase}" x:Name="dtGrid" HorizontalAlignment="Left" CanUserResizeRows="False" ItemsSource="{Binding}" GridLinesVisibility="All" HorizontalContentAlignment="Stretch" CanUserAddRows="false" SelectedCellsChanged="dtGrid_SelectedCellsChanged" VerticalAlignment="Top" Grid.ColumnSpan="2" DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainWindow}}}" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Year}" Header="Year"/>
<DataGridTextColumn Binding="{Binding Quarter}" Header="Quarter"/>
<DataGridTextColumn Binding="{Binding Name}" Header="Name"/>
<DataGridTextColumn Binding="{Binding SafetyScore}" Header="Safety Score"/>
<DataGridTextColumn Binding="{Binding ID}" Header="ID" Visibility="Collapsed"/>
</DataGrid.Columns>
</DataGrid>

MainWindow.cs

namespace Safety
{
public partial class MainWindow : MetroWindow
{
public MainWindow()
{
InitializeComponent();
DataContext = new SafetyViewModel();
string connectionString = "data Source=xxx; initial catalog=xxx; user id=xxx; password=xxx";
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("Select ID, Year, Quarter, Name, SaferyScore from MATRIX.dbo.Safety", connection);

try
{
connection.Open();
DataTable dt = new DataTable();
dt.Load(cmd.ExecuteReader());
dtGrid.DataContext = dt;
}

catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
connection.Close();
}

private void dtGrid_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
{
DataRowView row_selected = dtGrid.SelectedItem as DataRowView;
if (row_selected == null) return;
txtyr.ItemsSource = row_selected["Year"].ToString();
txtqt.Text = row_selected["Quarter"].ToString();
txtnm.Text = row_selected["Name"].ToString();
txtscc.Value = Convert.ToInt16(row_selected["SafetyScore"].ToString());
txtID.Text = row_selected["ID"].ToString();
}
}
}

SafetyViewModel.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Safety.Model;
using System.Windows;
using Safety;
using System.Collections.ObjectModel;

namespace Safety.ViewModel
{
public class SafetyViewModel : INotifyPropertyChanged
{
public SafetyViewModel()
{
this.loadyearlist();
this.loadnamelist();
this.loadquarterslist();
}

public void loadyearlist()
{
using (MATRIXEntities db = new MATRIXEntities())
{
var yrs = (from a in db.dimDate
select a).Distinct()
.ToList();

Years = new ObservableCollection<dimDate>(yrs);
}
}

public void loadquarterslist()
{
using (MATRIXEntities db = new MATRIXEntities())
{
var qts = (from a in db.dimDate
select a).Distinct()
.ToList();

Quarters = new ObservableCollection<dimDate>(qts);
}
}

public void loadnamelist()
{
using (MATRIXEntities db = new MATRIXEntities())
{
var nms = (from a in db.Employees
select a)
.ToList();

Employees = new ObservableCollection<Employees>(nms);
}
}



private ObservableCollection<dimDate> years;
public ObservableCollection<dimDate> Years
{
get { return years; }
set
{
years = value;
OnPropertyChanged("Years");
}
}

public string _years_SelectedValue;
private string years_SelectedValue
{
get { return _years_SelectedValue; }
set
{
_years_SelectedValue = value;
OnPropertyChanged("years_SelectedValue");
}
}

private ObservableCollection<dimDate> quarters;
public ObservableCollection<dimDate> Quarters
{
get { return quarters; }
set
{
quarters = value;
OnPropertyChanged("Quarters");
}
}

public string _quarters_SelectedValue;
private string quarters_SelectedValue
{
get { return _quarters_SelectedValue; }
set
{
_quarters_SelectedValue = value;
OnPropertyChanged("quarters_SelectedValue");
}
}

private ObservableCollection<Employees> employees;
public ObservableCollection<Employees> Employees
{
get { return employees; }
set
{
employees = value;
OnPropertyChanged("Employees");
}
}

public string _names_SelectedValue;
private string names_SelectedValue
{
get { return _names_SelectedValue; }
set
{
_names_SelectedValue = value;
OnPropertyChanged("names_SelectedValue");
}
}

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));

}
}

型号

namespace Safety.Model
{
using System;
using System.Collections.Generic;

public partial class dimDate
{
public int DateID { get; set; }
public System.DateTime Date { get; set; }
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
public int Quarter { get; set; }
}
}

namespace Safety.Model
{
using System;
using System.Collections.Generic;

public partial class Safety
{
public int ID { get; set; }
public int Year { get; set; }
public int Quarter { get; set; }
public string Name { get; set; }
public int SafetyScore { get; set; }
}
}

namespace Safety.Model
{
using System;
using System.Collections.Generic;

public partial class Employees
{
public int ID { get; set; }
public string Name { get; set; }
public string Position { get; set; }
}
}

最佳答案

你的代码有很多问题。下面列出了一些:

  • 绑定(bind)属性应该是公开的而不是私有(private)的
  • 在 Code behind 中,您试图设置 ComboBox 的 Text 而不是 SelectedValue
  • 您正在将代码隐藏与 ViewModel 设计混合

我编写了下面的代码来演示使用 MVVM 设计模式的要求。

MainWindow.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.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Margin="5" Grid.Column="0">
<Label Content="Year" />
<ComboBox x:Name="txtyr"
ItemsSource="{Binding Years}"
SelectedValue="{Binding Path=years_SelectedValue}" />
</StackPanel>
<StackPanel Margin="5" Grid.Column="1">
<Label Content="Quarter"/>
<ComboBox x:Name="txtqt"
ItemsSource="{Binding Quarters}"
SelectedValue="{Binding Path=quarters_SelectedValue}" />
</StackPanel>
<StackPanel Margin="5" Grid.Column="2">
<Label Content="Name" />
<ComboBox x:Name="txtnm"
ItemsSource="{Binding Names}"
SelectedValue="{Binding Path=names_SelectedValue}" />
</StackPanel>
</Grid>
<DataGrid Grid.Row="1" x:Name="dtGrid" ItemsSource="{Binding Safeties}" SelectedItem="{Binding SelectedSafety}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Year}" Header="Year"/>
<DataGridTextColumn Binding="{Binding Quarter}" Header="Quarter"/>
<DataGridTextColumn Binding="{Binding Name}" Header="Name"/>
<DataGridTextColumn Binding="{Binding SafetyScore}" Header="Safety Score"/>
<DataGridTextColumn Binding="{Binding ID}" Header="ID" Visibility="Collapsed"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>

为了演示,我在 View 中定义了 ViewModel。

MainViewModel.Cs

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;

namespace WpfApp1
{
public class MainWindowViewModel : INotifyPropertyChanged
{
public MainWindowViewModel()
{
var data = Model.GetData();
Safeties.AddRange(data);
Years.AddRange(data.Select(d => d.Year).Distinct());
Quarters.AddRange(data.Select(d => d.Quarter).Distinct());
Names.AddRange(data.Select(d => d.Name).Distinct());
}

private ObservableCollection<int> years = new ObservableCollection<int>();
public ObservableCollection<int> Years
{
get { return years; }
}

private int _years_SelectedValue;
public int years_SelectedValue
{
get { return _years_SelectedValue; }
set
{
_years_SelectedValue = value;
OnPropertyChanged("years_SelectedValue");
}
}

private ObservableCollection<int> quarters = new ObservableCollection<int>();
public ObservableCollection<int> Quarters
{
get { return quarters; }
}

private int _quarters_SelectedValue;
public int quarters_SelectedValue
{
get { return _quarters_SelectedValue; }
set
{
_quarters_SelectedValue = value;
OnPropertyChanged("quarters_SelectedValue");
}
}

private ObservableCollection<string> names = new ObservableCollection<string>();
public ObservableCollection<string> Names
{
get { return names; }
}

private string _names_SelectedValue;
public string names_SelectedValue
{
get { return _names_SelectedValue; }
set
{
_names_SelectedValue = value;
OnPropertyChanged("names_SelectedValue");
}
}

private ObservableCollection<Safety> safeties = new ObservableCollection<Safety>();
public ObservableCollection<Safety> Safeties
{
get { return safeties; }
}

private Safety selectedSafety;
public Safety SelectedSafety
{
get { return selectedSafety; }
set
{
selectedSafety = value;
this.OnPropertyChanged(nameof(SelectedSafety));
if (this.selectedSafety != null)
{
this.years_SelectedValue = selectedSafety.Year;
this.quarters_SelectedValue = selectedSafety.Quarter;
this.names_SelectedValue = selectedSafety.Name;
}
}
}

public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

通过上面的代码合并,下面的 gif 演示了该功能的工作原理:

enter image description here

附加代码

为了演示,我创建了一个类来获取数据

public static class Model
{
public static List<Safety> GetData()
{
return new List<Safety>()
{
new Safety() { ID = 1, Name = "First", Quarter = 1, SafetyScore = 1, Year = 2001 },
new Safety() { ID = 2, Name = "Second", Quarter = 2, SafetyScore = 1, Year = 2001 },
new Safety() { ID = 3, Name = "Third", Quarter = 3, SafetyScore = 1, Year = 2001 },
new Safety() { ID = 4, Name = "Fourth", Quarter = 4, SafetyScore = 1, Year = 2001 },
new Safety() { ID = 5, Name = "First", Quarter = 1, SafetyScore = 1, Year = 2002 },
new Safety() { ID = 6, Name = "Second", Quarter = 2, SafetyScore = 1, Year = 2002 },
new Safety() { ID = 7, Name = "Third", Quarter = 3, SafetyScore = 1, Year = 2002 },
new Safety() { ID = 8, Name = "Fourth", Quarter = 4, SafetyScore = 1, Year = 2002 },
};
}
}

ObservableCollection 的 AddRange 扩展。但是,您可以使用 C#7.0 中引入的 ObservableRangeCollection

public static class ObservableCollectionExtensions
{
public static void AddRange<T>(this ObservableCollection<T> observableCollection, IEnumerable<T> data)
{
foreach (T item in data)
{
observableCollection.Add(item);
}
}
}

安全.cs

public class Safety : INotifyPropertyChanged
{
private int id;
public int ID
{
get
{
return id;
}
set
{
id = value;
this.RaisePropertyChange(nameof(ID));
}
}

private int year;
public int Year
{
get
{
return year;
}
set
{
year = value;
this.RaisePropertyChange(nameof(ID));
}
}

private int quarter;
public int Quarter
{
get
{
return quarter;
}
set
{
quarter = value;
this.RaisePropertyChange(nameof(ID));
}
}

private string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
this.RaisePropertyChange(nameof(ID));
}
}

private int safetyScore;

public int SafetyScore
{
get
{
return safetyScore;
}
set
{
safetyScore = value;
this.RaisePropertyChange(nameof(ID));
}
}

public event PropertyChangedEventHandler PropertyChanged;

private void RaisePropertyChange(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

关于c# - 如何将不同的查询结果绑定(bind)到组合框并将其作为选定的单元格值传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58490556/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com