WPF的ComboBox中选定值

WPF的ComboBox中选定值

问题描述:

我'在我的DataGrid视图组合框挣扎。WPF的ComboBox中选定值

我有2个观察的集合。一个用于数据网格,其中列DDV显示Combobox的选定项目,其次是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是:

enter image description here

显而易见的是,所选的项目不能正常工作。我做错了什么?

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

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

DDV物业在ArtikliStoritve模型:

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

我也注意到,当我在ComboBox中第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。我测试了在comboBox的所有选项为(getAll())或集合ArtikliStoritveData的对象中创建的选定值。两人都没有工作。

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

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

enter image description here

如果做到这一点在WPF ,Combobox中的选定值是列表中的第一个值,不是正确的:

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

最后我找到了解决方案。 SelectedValue和SelectedValuePath的Conjuction做了诀窍。

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

关于link我找到了帮助我的其他信息。

问候, 伊戈尔

+0

什么不起作用? –

+0

看起来像'DDV_Data'不是数据项的属性,它绑定到网格行。如果您在Visual Studio中查看输出窗口,则会看到绑定错误。 – Dennis

+0

我在输出窗口中没有任何错误。我发布了一个代码,证明DDV_Data是集合od ArtikliStoritveData的一部分。 – Igor

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

从你的代码,它好像绑定到ItemsSource财产在收集你的数据是一个自定义类的类型......你没有表现出这一点,但我猜,因为你设置的DisplayMemberPath的值的Naziv。因此,无论你需要让你的数据绑定到SelectedItem属性相同类型的集合中的内容会DDV属性,或者你可以尝试使用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 >>>

您最新的编辑是我建议。尽管如此,现在您已经添加了相关的代码,我可以看到ArtikliStoritveDataArtikliStoritve类型的集合,DDV_Data是该类中的一个属性,它是DDV_Class类型的集合。因此,你需要一个属性DDV_Class型也在你ArtikliStoritve类,您可以绑定到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 Error: 40 : BindingExpression path error: 'Some' property not found on 'object' ''NameOfDataBoundObject' (Name='')'. BindingExpression:Path=SomePath; DataItem='NameOfDataBoundObject' (Name=''); target element is 'TypeOfUiElement' (Name='NameOfUiElement'); target property is 'PropertyName' (type 'TypeOfProperty')

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

+0

在输出窗口中,我得到: ystem.Windows.Data错误:7:ConvertBack无法转换值'Risa.Model.DDV_Class'(类型'DDV_Class')。 BindingExpression:路径=的SelectedItem; DataItem ='ArtikliStoritve'(HashCode = 34092959);目标元素是'ComboBox'(Name ='cmbDDV');目标属性是'SelectedItem'(类型'Object')NotSupportedException:'System.NotSupportedException:DecimalConverter不能从Risa.Model.DDV_Class转换。 – Igor

+0

您是否像投递答案一样删除SelectdItem? – Paparazzi

+0

是的。它仍然不起作用 – Igor

我在问题的最后添加了解决方案。

Regards, Igor