在WPF组合框选择的值(WPF selected value in ComboBox)

2019-10-29 17:55发布

我'在我的DataGrid中查看与组合框挣扎。

我有2个观察的集合。 一个用于数据网格,列DDV礼物选择组合框的项目和第二哪里是CombBox所有选项。

观察集合DDV_Data(所有组合框选项)是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>

而我的结果的DataGrid是:

很明显,选择的项目不能正常工作。 做什么我'错了吗?

我也想知道为什么在组合框新行不会被绑定?

DDV_Data是被绑定到DataGrid中观察到的集合的一部分:

                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(),
                    DDV = Convert.ToDecimal(dt.Rows[i]["ddv"].ToString()),
                    DDV_Data = DDV_Data1,
                    SelectedItem = "22.0",
                    Znesek = Decimal.Parse(dt.Rows[i]["znesek"].ToString()) ,
                    DatumSpremembe = DateTime.Parse(dt.Rows[i]["date_changed"].ToString())
                });    

物业税和ArtikliStoritve模型:

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

我也注意到,当我在第i个组合框每行的变化而变化值???

ArtikliStoritve:

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
}

对于组合框我有一个类:

class DDV_Class
{
    private int _ID;
    public int ID
    {
        get { return _ID; }
        set { _ID = value; }
    }

    private decimal _DDV;
    public decimal DDV
    {
        get { return _DDV; }
        set { _DDV = 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())
    });
}

- >更新

我做了什么。 在ArtikliStoritve:

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

当填充:

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())
    });        
}

在ArtikliStoritveModelView我也有属性:

public DDV_Class SelectedItem
{
    get { return ArtikliStoritve.SelectedItem; }
    set { ArtikliStoritve.SelectedItem = value; OnPropertyChanged("SelectedItem"); }
}

WPF是这样的:

<DataTemplate>
    <ComboBox
        x:Name="cmbDDV"
        ItemsSource="{Binding DDV_Data}"
        DisplayMemberPath="DDV"
        SelectedItem="{Binding Path=SelectedItem}"
        IsSynchronizedWithCurrentItem="True"
        Width="50"
    />
</DataTemplate>

结果是上述同一象图象被示出。

- >更新我弄明白为什么在所有行的值改变,当我在组合框一行变化值。 问题VAS怎么一回事,因为我观察到的集合中的每一行一个istance补充说:

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,
            ...

我做我的另一列其中,这是现在的工作测试:

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;

现在为什么不获取在ComboBox中选定值我必须弄明白。 余与对象创建选择的值进行测试,其中对组合框的所有选项是(GETALL()),或在收集ArtikliStoritveData。 无论是一个正在工作。

继续寻找合适的解决方案... :)

如果我在一排检索算法contect,探听我看这个(这是正确的):

如果这样做的WPF,在ComboBox中选定值列表中,不正确的第一个值:

<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"
/>

在联系 ,我发现更多的信息这帮助了我。

问候,伊戈尔

Answer 1:

我想,我能看到你的错误是什么?当数据绑定到ComboBox.SelectedItem财产,有几件事情要注意。 第一个是绑定到对象数据SelectedItem属性必须是相同的类型因为这是绑定到数据集合中的项 ItemsSource属性。

从你的代码,它好像绑定在收集你的数据ItemsSource属性是一个自定义类的类型......你没有表现出这一点,但我猜,因为你设置DisplayMemberPath为值Naziv 。 因此,无论你需要让你的DDV您数据绑定到财产SelectedItem属性相同类型的集合中的项目,或者你可以尝试使用ComboBox.SelectedValue与联合产权SelectedValuePath属性,而不是:

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

UPDATE >>>

您最新的编辑是不是我的建议。 都是一样的,现在你已经加入了相关的代码,我可以看到, ArtikliStoritveData是类型的集合ArtikliStoritveDDV_Data是在类,这是类型集合的属性DDV_Class 。 因此,你需要一个属性类型也DDV_ClassArtikliStoritve类,您可以绑定到SelectedIten属性:

<ComboBox x:Name="cmbDDV" 
    ItemsSource="{Binding Path=DDV_Data}"
    SelectedItem="{Binding Path=SelectedItem}"
    IsSynchronizedWithCurrentItem="True"
    Width="50" />

...

private DDV_Class _SelectedItem;
public DDV_Class 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; }
}

只是一对夫妇的事情,说明此处为未来......如果你想设置ComboBox.SelectedItem从代码,你设置为值必须绑定到该集合的实际项目的项目ComboBox.ItemsSource属性。 你可以像下面这样做:

SelectedItem = DDV_Data.Where(d => d.ID == someIdValue).Single();

此外,你应该已经得到了在Visual Studio中的输出窗口显示了一些错误......是这样的:

System.Windows.Data错误:40:BindingExpression路径错误:对 '对象' '' NameOfDataBoundObject '(名称= '')' 未找到 '某些' 属性。 BindingExpression:路径= SomePath; 的DataItem = 'NameOfDataBoundObject'(名称= ''); 目标元素是 'TypeOfUiElement'(名称= 'NameOfUiElement'); 目标属性是“属性名”(类型“TypeOfProperty”)

这些都是有价值的线索......注意他们,因为他们帮助你跟踪你的问题。



Answer 2:

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

问候,伊戈尔



文章来源: WPF selected value in ComboBox