从视图模型中的 observablecollection 绑定到组合框数据模板

发布于 2025-01-11 04:08:12 字数 5123 浏览 0 评论 0原文

我试图让组合框反映此项目更新时底层视图模型中的更改,我尝试遵循 MVVM 方法并使用 INotifypropertyChanged 但无论我尝试什么,我都缺少一些东西来实现此目的发生。

我很确定我的 DataContext 正确 - PropertyChanged 事件触发,该集合是从我的 DAL 填充的,我尝试指定 SourceUpdateTrigger在组合框的 xaml 中 - 我只是无法弄清楚接线的断点在哪里。我们将非常感谢您的帮助,也很乐意提供常见示例的指导。

的 XAML

<ComboBox  ItemsSource="{Binding partsResultsCollection}" x:Name="searchInput" TextBoxBase.TextChanged="searchInput_TextChanged" HorizontalAlignment="Left" Margin="231,88,0,0" VerticalAlignment="Top" Width="316" Height="25" IsEditable="True">
         <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock FontWeight="Bold" Text="PartNO:"/>
                    <TextBlock Text="{Binding Path=PartNumber}" Padding="10,0"/>
                    <TextBlock FontWeight="Bold" Text="DESC:"/>
                    <TextBlock Text="{Binding Path=Description}" Padding="10,0"/>
                    <TextBlock FontWeight="Bold" Text="QOH:"/>
                    <TextBlock Text="{Binding Path=QtyOnHand}" Padding="10,0"/>
                    <TextBlock FontWeight="Bold" Text="WHQ:"/>
                    <TextBlock Text="{Binding Path=WarehouseQTY}" Padding="10,0"/>
                    <TextBlock FontWeight="Bold" Text="LastSold:"/>
                    <TextBlock Text="{Binding Path=LastSold}" Padding="10,0"/>
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

组合框ViewModel 类

class PartsResultsVM : INotifyPropertyChanged
{
    public ObservableCollection<PartsResults> _partsResultsCollection;
    private PartsResults _singularPartResult;
    public PartsDAL partsDAL = new PartsDAL();

    public ObservableCollection<PartsResults> partsResultsCollection
    {
        get { return _partsResultsCollection; }
        set {
              if (partsResultsCollection != value)
                _partsResultsCollection = value;
            OnPropertyChanged("partsResultCollection");
         }
    }

    public PartsResults singularPartResult
    {
        get { return _singularPartResult; }
        set {
              if (singularPartResult != value)
            {
                _singularPartResult = value;
                OnPropertyChanged("singularPart");
            }
            _singularPartResult = value; }
    }

    public PartsResultsVM()
    {
        _partsResultsCollection = new ObservableCollection<PartsResults>();
    }

    public void Update(String Query)
    {
        _partsResultsCollection.Clear();

        _partsResultsCollection = partsDAL.getPartListing(Query);
        OnPropertyChanged("Update");
        Debug.WriteLine("partresultcollection contains:" + _partsResultsCollection.Count + " Items");
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
            Debug.WriteLine("PropertyChanged event fired info " + info);
        }
    }

包含组合框的页面

public partial class PartsManagement : Page
{
    private String connectionString;
    private PartsResultsVM partsResultsVM;

    public PartsManagement()
    {
        InitializeComponent();
        connectionString = @"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = C:\Register\SourceCode\DataBase\Medicar.mdb";
        partsResultsVM = new PartsResultsVM();
        this.DataContext = partsResultsVM;
    }

    private void searchInput_TextChanged(object sender, TextChangedEventArgs e)
    {
        partsResultsVM.Update(searchInput.Text);
    }
} 

添加部分结果模型类

public class PartsResults 
{
    private string partNumber; 
    private string description;
    private int qtyOnHand;
    private int warehouseQTY;
    private DateTime lastSupplied;

    public string PartNumber
    {
        get {return partNumber;}
        set 
        { 
            partNumber = value;
            //this.RaisePropertyChanged("Partnumber");          
        }
    }

    public string Description 
    {
        get {return description;}
        set
        {
            description = value;
            //this.RaisePropertyChanged("Description");
        }
    }

    public int QtyOnHand 
    {
        get{return qtyOnHand;}
        set
        {
            qtyOnHand = value;
           // this.RaisePropertyChanged("QtyOnHand");
        }
    }

    public int WarehouseQTY
    {
        get{return warehouseQTY;}
        set
        {
            warehouseQTY = value;
            //this.RaisePropertyChanged("WarehouseQTY");
        }
    }

    public DateTime LastSupplied
    {
        get { return lastSupplied; }
        set
        {
            lastSupplied = value;
           // this.RaisePropertyChanged("LastSupplied");
        }
    }
}

I am trying to have a combobox reflect the changes in the underlying viewmodel when this item updates, I have tried to follow the MVVM approach and using INotifypropertyChanged but no matter what I try I am missing something to have this happen.

I am pretty sure I have the DataContext correct - the PropertyChanged event fires, the collection is populated from my DAL, I have tried specifying the SourceUpdateTrigger in the xaml for the combobox - I just cant figure where the break in the wiring is. Your help would be greatly appreciated, happy for direction to usual examples too.

XAML for combobox

<ComboBox  ItemsSource="{Binding partsResultsCollection}" x:Name="searchInput" TextBoxBase.TextChanged="searchInput_TextChanged" HorizontalAlignment="Left" Margin="231,88,0,0" VerticalAlignment="Top" Width="316" Height="25" IsEditable="True">
         <ComboBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock FontWeight="Bold" Text="PartNO:"/>
                    <TextBlock Text="{Binding Path=PartNumber}" Padding="10,0"/>
                    <TextBlock FontWeight="Bold" Text="DESC:"/>
                    <TextBlock Text="{Binding Path=Description}" Padding="10,0"/>
                    <TextBlock FontWeight="Bold" Text="QOH:"/>
                    <TextBlock Text="{Binding Path=QtyOnHand}" Padding="10,0"/>
                    <TextBlock FontWeight="Bold" Text="WHQ:"/>
                    <TextBlock Text="{Binding Path=WarehouseQTY}" Padding="10,0"/>
                    <TextBlock FontWeight="Bold" Text="LastSold:"/>
                    <TextBlock Text="{Binding Path=LastSold}" Padding="10,0"/>
                </StackPanel>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

ViewModel Class

class PartsResultsVM : INotifyPropertyChanged
{
    public ObservableCollection<PartsResults> _partsResultsCollection;
    private PartsResults _singularPartResult;
    public PartsDAL partsDAL = new PartsDAL();

    public ObservableCollection<PartsResults> partsResultsCollection
    {
        get { return _partsResultsCollection; }
        set {
              if (partsResultsCollection != value)
                _partsResultsCollection = value;
            OnPropertyChanged("partsResultCollection");
         }
    }

    public PartsResults singularPartResult
    {
        get { return _singularPartResult; }
        set {
              if (singularPartResult != value)
            {
                _singularPartResult = value;
                OnPropertyChanged("singularPart");
            }
            _singularPartResult = value; }
    }

    public PartsResultsVM()
    {
        _partsResultsCollection = new ObservableCollection<PartsResults>();
    }

    public void Update(String Query)
    {
        _partsResultsCollection.Clear();

        _partsResultsCollection = partsDAL.getPartListing(Query);
        OnPropertyChanged("Update");
        Debug.WriteLine("partresultcollection contains:" + _partsResultsCollection.Count + " Items");
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
            Debug.WriteLine("PropertyChanged event fired info " + info);
        }
    }

The Page containing the combobox

public partial class PartsManagement : Page
{
    private String connectionString;
    private PartsResultsVM partsResultsVM;

    public PartsManagement()
    {
        InitializeComponent();
        connectionString = @"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = C:\Register\SourceCode\DataBase\Medicar.mdb";
        partsResultsVM = new PartsResultsVM();
        this.DataContext = partsResultsVM;
    }

    private void searchInput_TextChanged(object sender, TextChangedEventArgs e)
    {
        partsResultsVM.Update(searchInput.Text);
    }
} 

Adding partresult model class

public class PartsResults 
{
    private string partNumber; 
    private string description;
    private int qtyOnHand;
    private int warehouseQTY;
    private DateTime lastSupplied;

    public string PartNumber
    {
        get {return partNumber;}
        set 
        { 
            partNumber = value;
            //this.RaisePropertyChanged("Partnumber");          
        }
    }

    public string Description 
    {
        get {return description;}
        set
        {
            description = value;
            //this.RaisePropertyChanged("Description");
        }
    }

    public int QtyOnHand 
    {
        get{return qtyOnHand;}
        set
        {
            qtyOnHand = value;
           // this.RaisePropertyChanged("QtyOnHand");
        }
    }

    public int WarehouseQTY
    {
        get{return warehouseQTY;}
        set
        {
            warehouseQTY = value;
            //this.RaisePropertyChanged("WarehouseQTY");
        }
    }

    public DateTime LastSupplied
    {
        get { return lastSupplied; }
        set
        {
            lastSupplied = value;
           // this.RaisePropertyChanged("LastSupplied");
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

丑疤怪 2025-01-18 04:08:12

我想我明白这个问题了。您需要 ICollectionView 接口来显示数据。在这里您可以找到更多详细信息。

CollectionView

应用ViewModel 中的以下更改。

public ICollectionView partsResultsCollectionView { get; private set; }

public ObservableCollection<PartsResults> partsResultsCollection = new ObservableCollection<PartsResults>();

public PartsResultsVM()
{
    partsResultsCollectionView = CollectionViewSource.GetDefaultView(partsResultsCollection);
    partsResultsCollection.Add(new PartsResults { PartNumber = "PartNumber1", Description = "Description1", LastSold = "LastSold1", QtyOnHand = "QtyOnHand1", WarehouseQTY = "WarehouseQTY1" });
}

如果您想要对之前添加的 PartResults 元素进行更改。您应该为每个项目实现 INotifyPropertyChanged。

注意:我没有看到您添加 PartResults 类。所以我假设它们都是字符串。你解决它:)

I think I understand the problem. You need the ICollectionView interface to display the data. Here you can find more detailed information.

CollectionView

Apply the following changes in the ViewModel.

public ICollectionView partsResultsCollectionView { get; private set; }

public ObservableCollection<PartsResults> partsResultsCollection = new ObservableCollection<PartsResults>();

public PartsResultsVM()
{
    partsResultsCollectionView = CollectionViewSource.GetDefaultView(partsResultsCollection);
    partsResultsCollection.Add(new PartsResults { PartNumber = "PartNumber1", Description = "Description1", LastSold = "LastSold1", QtyOnHand = "QtyOnHand1", WarehouseQTY = "WarehouseQTY1" });
}

If you want to make changes in a previously added PartResults element. You should implement INotifyPropertyChanged for each item.

Note : I didn't see you add the PartResults class. So I assumed they were all strings. You fix it :)

甜柠檬 2025-01-18 04:08:12

因此,问题似乎出在此处从 DAL 分配结果时

_partsResultsCollection = partsDAL.getPartListing(Query);

,它不会触发“ObservableCollection.CollectionChanged 事件”

https://learn.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1.collectionchanged?view=net-6.0

绑定到组合框的 ObservableCollection 没有 通知更改

更新 ObservableCollection 时

        results = partsDAL.getPartListing(Query);

        foreach (PartsResults partsResults in results)
        {
            _partsResultsCollection.Add(partsResults);
        }

,如下所示,没有其他修改,组合框按预期填充。

So it appears that the issue was with the assigning of the results from the DAL here

_partsResultsCollection = partsDAL.getPartListing(Query);

which does not fire a "ObservableCollection.CollectionChanged Event"

https://learn.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1.collectionchanged?view=net-6.0

the ObservableCollection bound to the combobox did not notify of changes

when updating the ObservableCollection as follows

        results = partsDAL.getPartListing(Query);

        foreach (PartsResults partsResults in results)
        {
            _partsResultsCollection.Add(partsResults);
        }

with no other modifications the combobox populated as expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文