C# 组合框中的WPF选定值

C# 组合框中的WPF选定值,c#,wpf,mvvm,datagrid,combobox,C#,Wpf,Mvvm,Datagrid,Combobox,我正在努力在我的DataGrid视图中使用ComboBox 我有两个可观察的集合。一个用于数据网格,其中DDV列表示Combobox的选定项,第二个用于Combobox的所有选项 可观测收集DDV_数据(所有组合框选项)位于ArtikliStoritveData的可观测收集中 我的WPF如下所示: <DataGrid ItemsSource="{Binding Path=ArtikliStoritveData}" AutoGenerateColumns="False" Se

我正在努力在我的DataGrid视图中使用ComboBox

我有两个可观察的集合。一个用于数据网格,其中DDV列表示Combobox的选定项,第二个用于Combobox的所有选项

可观测收集DDV_数据(所有组合框选项)位于ArtikliStoritveData的可观测收集中

我的WPF如下所示:

        <DataGrid ItemsSource="{Binding Path=ArtikliStoritveData}" AutoGenerateColumns="False" SelectionMode="Single" CanUserAddRows="True" x:Name="dgArtikliStoritve" HorizontalAlignment="Left" Margin="31,58,0,0" VerticalAlignment="Top" Height="229" Width="612">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Šifra" Binding="{Binding Sifra}" />
            <DataGridTextColumn Header="Naziv" Binding="{Binding Naziv}" Width="200"/>
            <DataGridTextColumn Header="Znesek" Binding="{local:CultureAwareBinding Path=Znesek, StringFormat={}{0:C}}"/>
            <DataGridTextColumn Header="DDV" Binding="{local:CultureAwareBinding Path=DDV}" />
            <DataGridTextColumn Header="EM" Binding="{Binding EM}" />
            <DataGridTextColumn Header="Datum spremembe" Binding="{local:CultureAwareBinding Path=DatumSpremembe}" />
            <DataGridTemplateColumn Header="DDV">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox
                            x:Name="cmbDDV"
                            ItemsSource="{Binding DDV_Data}"
                            SelectedValuePath="DDV"
                            DisplayMemberPath="DDV"
                            SelectedValue="{Binding DDV1}"
                            IsSynchronizedWithCurrentItem="True"
                            Width="50"
                        />
                        </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Binding="{Binding Artikel_ID}" Width="0" Visibility="Hidden"/>
            <DataGridTextColumn Binding="{Binding SkupinaArtikla}" Width="0" Visibility="Hidden"/>
        </DataGrid.Columns>
    </DataGrid>
<DataTemplate>
    <ComboBox
        x:Name="cmbDDV"
        ItemsSource="{Binding DDV_Data}"
        DisplayMemberPath="DDV"
        SelectedItem="{Binding Path=SelectedItem}"
        IsSynchronizedWithCurrentItem="True"
        Width="50"
    />
</DataTemplate>
SelectedItem = DDV_Data.Where(d => d.ID == someIdValue).Single();
ArtiklStoritve模型中的DDV属性:

    public decimal DDV
    {
        get { return _ddv; }
        set { _ddv = value; }
我还注意到,当我改变ComboBox中的值时,每一行的值都会改变

艺术史:

class ArtikliStoritve
{

    #region private varaibles
    int _artikel_id;
    int _skupinaArtikla;
    string _sifra;
    string _naziv;
    string _EM;
    decimal _ddv;
    decimal _znesek;
    DateTime _datum_spremembe;

    #endregion

    #region properties
    public int Artikel_ID
    {
        get { return _artikel_id; }
        set { _artikel_id = value; }
    }

    public int SkupinaArtikla
    {
        get { return _skupinaArtikla; }
        set { _skupinaArtikla = value; }
    }

    public string Sifra
    {
        get { return _sifra; }
        set { _sifra = value; }
    }

    public string EM
    {
        get { return _EM; }
        set { _EM = value; }
    }

    public string Naziv
    {
        get { return _naziv; }
        set { _naziv = value; }
    }

    public decimal DDV1
    {
        get { return _ddv; }
        set { _ddv = value; }
    }

    public decimal Znesek
    {
        get { return _znesek;}
        set { _znesek = value; }
    }

    public DateTime DatumSpremembe
    {
        get { return _datum_spremembe; }
        set { _datum_spremembe = value; }
    }

    private decimal _SelectedItem;
    public decimal SelectedItem
    {
        get { return _SelectedItem; }
        set { _SelectedItem = value; }
    }

    private ObservableCollection<DDV_Class> _DDV_Data = new ObservableCollection<DDV_Class>();
    public ObservableCollection<DDV_Class> DDV_Data
    {
        get { return _DDV_Data; }
        set { _DDV_Data = value; }
    }
    #endregion
}
private DDV_Class _SelectedItem;
public DDV_Class SelectedItem
{
    get { return _SelectedItem; }
    set { _SelectedItem = value; }
}
我在ArtikliStoritveViewModel中填写:

for (int i = 0; i < dtDDV.Rows.Count; i++)
{
    DDV_Data1.Add(new DDV_Class
    {
        ID = Convert.ToInt32(dtDDV.Rows[i]["ID"].ToString()),
        DDV = Convert.ToDecimal(dtDDV.Rows[i]["DDV"].ToString())
    });
}
填充时:

for (int i = 0; i < dt.Rows.Count; ++i)
{
    ArtikliStoritveData.Add(new ArtikliStoritve
    {
        Artikel_ID = Convert.ToInt32(dt.Rows[i]["artikel_id"].ToString()),
        SkupinaArtikla = Convert.ToInt32(dt.Rows[i]["skupina_artikla"].ToString()),
        Sifra = dt.Rows[i]["sifra"].ToString(),
        EM = dt.Rows[i]["em"].ToString(),
        Naziv = dt.Rows[i]["naziv"].ToString(),
        DDV1 = Convert.ToDecimal(dt.Rows[i]["ddv"].ToString()),
        DDV_Data = DDV_Data1,
        SelectedItem = new DDV_Class { ID = 1, DDV = 22.0m },
        Znesek = Decimal.Parse(dt.Rows[i]["znesek"].ToString()),
        DatumSpremembe = DateTime.Parse(dt.Rows[i]["date_changed"].ToString())
    });        
}
WPF如下所示:

        <DataGrid ItemsSource="{Binding Path=ArtikliStoritveData}" AutoGenerateColumns="False" SelectionMode="Single" CanUserAddRows="True" x:Name="dgArtikliStoritve" HorizontalAlignment="Left" Margin="31,58,0,0" VerticalAlignment="Top" Height="229" Width="612">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Šifra" Binding="{Binding Sifra}" />
            <DataGridTextColumn Header="Naziv" Binding="{Binding Naziv}" Width="200"/>
            <DataGridTextColumn Header="Znesek" Binding="{local:CultureAwareBinding Path=Znesek, StringFormat={}{0:C}}"/>
            <DataGridTextColumn Header="DDV" Binding="{local:CultureAwareBinding Path=DDV}" />
            <DataGridTextColumn Header="EM" Binding="{Binding EM}" />
            <DataGridTextColumn Header="Datum spremembe" Binding="{local:CultureAwareBinding Path=DatumSpremembe}" />
            <DataGridTemplateColumn Header="DDV">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox
                            x:Name="cmbDDV"
                            ItemsSource="{Binding DDV_Data}"
                            SelectedValuePath="DDV"
                            DisplayMemberPath="DDV"
                            SelectedValue="{Binding DDV1}"
                            IsSynchronizedWithCurrentItem="True"
                            Width="50"
                        />
                        </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Binding="{Binding Artikel_ID}" Width="0" Visibility="Hidden"/>
            <DataGridTextColumn Binding="{Binding SkupinaArtikla}" Width="0" Visibility="Hidden"/>
        </DataGrid.Columns>
    </DataGrid>
<DataTemplate>
    <ComboBox
        x:Name="cmbDDV"
        ItemsSource="{Binding DDV_Data}"
        DisplayMemberPath="DDV"
        SelectedItem="{Binding Path=SelectedItem}"
        IsSynchronizedWithCurrentItem="True"
        Width="50"
    />
</DataTemplate>
SelectedItem = DDV_Data.Where(d => d.ID == someIdValue).Single();

结果和上面显示的图片一样

-->更新 当我在一行中更改comboBox中的值时,我明白了为什么所有行中的值都会更改。问题vas,因为我在每行添加了一个可观察集合的距离:

DDV_Data1不是为每行实例化的,因此这是一个问题-所有行中都有一个对象:

DataTable dtDDV = myDDV_DAL.getAll();
if (dtDDV.Rows.Count > 0)
{
    for (int i = 0; i < dtDDV.Rows.Count; i++)
    {
        DDV_Data1.Add(new DDV_Class
        {
            ID = Convert.ToInt32(dtDDV.Rows[i]["ID"].ToString()),
            DDV = Convert.ToDecimal(dtDDV.Rows[i]["DDV"].ToString())
        });
    }
}

ArtikliStoritveDAL myArtikliStoritveDAL  = new ArtikliStoritveDAL();
DataTable dt = myArtikliStoritveDAL.getAll();
if (dt.Rows.Count > 0)
{
    for (int i = 0; i < dt.Rows.Count; ++i)
    {
        ArtikliStoritveData.Add(new ArtikliStoritve
        {
            ...
            DDV_Data = DDV_Data1,
            ...
DataTable dtDDV=myDDV_DAL.getAll();
如果(dtDDV.Rows.Count>0)
{
对于(int i=0;i0)
{
对于(int i=0;i
我在另一个专栏上进行了测试,现在这一功能正在发挥作用:

EM_DAL myEM_DAL = new EM_DAL();
DataTable dtEM = myEM_DAL.getAll();
if (dtEM.Rows.Count > 0)
{
    for (int i = 0; i < dtEM.Rows.Count; i++)
    {
        EM_Data.Add(new EM_Model
        {
            ID = dtEM.Rows[i]["EM"].ToString(),
            Naziv = dtEM.Rows[i]["EM"].ToString()
        });
    }
}

    ArtikliStoritveDAL myArtikliStoritveDAL  = new ArtikliStoritveDAL();
DataTable dt = myArtikliStoritveDAL.getAll();
if (dt.Rows.Count > 0)
{
    for (int i = 0; i < dt.Rows.Count; ++i)
    {
        ArtikliStoritveData.Add(new ArtikliStoritve
        {
            ...
            EM_Data = getAll(dt.Rows[i]["em"].ToString()),
            ...


public List<EM_Model> getAll(string p_selected)
{
    List<EM_Model> myEM_Model = new List<EM_Model>();
    string strConnString = Util.getConnectionString();
    try
    {
        NpgsqlConnection conn = new NpgsqlConnection(strConnString);
        DataTable dt = new DataTable();
        conn.Open();
        NpgsqlDataAdapter da = new NpgsqlDataAdapter("SELECT em, em "
                                                        + " FROM em", conn);
        da.Fill(dt);
        conn.Close();
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            myEM_Model.Add(new EM_Model
            {
                ID = dt.Rows[i]["EM"].ToString(),
                Naziv = dt.Rows[i]["EM"].ToString(),
                SelectedItem1 = p_selected
            });
        }
        return myEM_Model;
EM_DAL myEM_DAL=新的EM_DAL();
DataTable dtEM=myEM_DAL.getAll();
如果(dtEM.Rows.Count>0)
{
对于(int i=0;i0)
{
对于(int i=0;i
现在我必须弄清楚为什么在comboBox中没有选择is value。我使用在comboBox的所有选项都为(getAll())的对象或集合ArtikliStoritveData中创建的选定值进行了测试。两者都不起作用

继续搜索正确的解决方案…:)

如果我将serach contect放在一行,Snoop会向我显示以下内容(正确):

如果在WPF中执行此操作,则组合框中的选定值是列表中的第一个值,而不是正确的值:

<ComboBox
    x:Name="cmbEM"
    ItemsSource="{Binding EM_Data}"
    DisplayMemberPath="Naziv"
    SelectedItem="{Binding EM}"
    IsSynchronizedWithCurrentItem="True"
    Width="50"
/>

最后,我找到了一个解决方案。SelectedValue和SelectedValuePath的结合成功了

<ComboBox
    x:Name="cmbDDV"
    ItemsSource="{Binding DDV_Data}"
    DisplayMemberPath="DDV"
    SelectedValue="{Binding DDV, Mode=TwoWay}" 
    SelectedValuePath="DDV" 
    IsSynchronizedWithCurrentItem="True"
    Width="50"
/>

在网上,我发现了一些对我有帮助的信息

问候,,
Igor

我想我可以看到您的错误所在…当数据绑定到组合框时。SelectedItem
属性,有几点需要注意。第一点是绑定到
SelectedItem
属性的对象数据必须与绑定到
ItemsSource
属性的集合中的项具有相同的类型

从您的代码中,似乎绑定到
ItemsSource
属性的数据集合属于自定义类的类型……您没有显示,但我猜是因为您将
DisplayMemberPath
的值设置为
Naziv
。因此您需要将数据绑定到
DDV
属性
SelectedItem
属性的类型与集合中的项相同,或者您可以尝试使用
组合框。SelectedValue
属性与
SelectedValuePath
属性组合使用:

<ComboBox x:Name="cmbDDV" 
    ItemsSource="{Binding Path=DDV_Data}"
    DisplayMemberPath="Naziv"
    SelectedValuePath="Naziv"
    IsSynchronizedWithCurrentItem="True"
    SelectedValue="{Binding Path=DDV}"
    Width="50" />
这里有几点需要注意,以备将来使用……如果要设置
组合框。请从代码中选择EdItem
,设置为值的项必须是绑定到
组合框的集合中的实际项。ItemsSource
属性。您可以这样做:

        <DataGrid ItemsSource="{Binding Path=ArtikliStoritveData}" AutoGenerateColumns="False" SelectionMode="Single" CanUserAddRows="True" x:Name="dgArtikliStoritve" HorizontalAlignment="Left" Margin="31,58,0,0" VerticalAlignment="Top" Height="229" Width="612">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Šifra" Binding="{Binding Sifra}" />
            <DataGridTextColumn Header="Naziv" Binding="{Binding Naziv}" Width="200"/>
            <DataGridTextColumn Header="Znesek" Binding="{local:CultureAwareBinding Path=Znesek, StringFormat={}{0:C}}"/>
            <DataGridTextColumn Header="DDV" Binding="{local:CultureAwareBinding Path=DDV}" />
            <DataGridTextColumn Header="EM" Binding="{Binding EM}" />
            <DataGridTextColumn Header="Datum spremembe" Binding="{local:CultureAwareBinding Path=DatumSpremembe}" />
            <DataGridTemplateColumn Header="DDV">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox
                            x:Name="cmbDDV"
                            ItemsSource="{Binding DDV_Data}"
                            SelectedValuePath="DDV"
                            DisplayMemberPath="DDV"
                            SelectedValue="{Binding DDV1}"
                            IsSynchronizedWithCurrentItem="True"
                            Width="50"
                        />
                        </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Binding="{Binding Artikel_ID}" Width="0" Visibility="Hidden"/>
            <DataGridTextColumn Binding="{Binding SkupinaArtikla}" Width="0" Visibility="Hidden"/>
        </DataGrid.Columns>
    </DataGrid>
<DataTemplate>
    <ComboBox
        x:Name="cmbDDV"
        ItemsSource="{Binding DDV_Data}"
        DisplayMemberPath="DDV"
        SelectedItem="{Binding Path=SelectedItem}"
        IsSynchronizedWithCurrentItem="True"
        Width="50"
    />
</DataTemplate>
SelectedItem = DDV_Data.Where(d => d.ID == someIdValue).Single();
此外,您应该在Visual Studio的输出窗口中显示一些错误…类似于:

System.Windows.Data错误:40:BindingExpression路径错误:“在”“对象”“数据边界对象的名称”“(名称=“”)”上找不到某些属性。BindingExpression:path=SomePath;DataItem='DataBoundObject的名称”“(名称=“”);目标元素为'TypeOfIELEment'(名称=“”);目标属性为'PropertyName'(类型为'TypeOfProperty')


这些都是有价值的线索……请注意它们,因为它们有助于你追踪你的问题。

我在问题的末尾添加了解决方案

问候,,
Igor

看起来像是
DDV_数据
不是绑定到网格行的数据项的属性。如果您查看Visual Studio中的输出窗口,您将看到绑定错误。我在输出窗口中没有任何错误。我发布了一段代码,证明DDV_数据是collec的一部分