【问题标题】:bindings in my WPF combobox are not working?我的 WPF 组合框中的绑定不起作用?
【发布时间】:2013-05-24 01:07:10
【问题描述】:

我有一个 ListView,它显示一个图像、两个文本框和一个组合框。 ListView 绑定到我的视图模型中的集合。 Combobox 绑定到我的视图模型中的另一个集合,所选项目绑定到列表视图中对象的属性。
预期结果:对于每个项目,组合框将显示当前图像中的值。然后用户应该能够在下拉列表中选择一个新值并将其分配给图像对象。

我得到的是:一个空白的组合框!当我单击 v 时,它会显示所有未显示名称的项目!

我的视图模型(它必须存在于我们当前应用程序设计的结构中)为简洁起见,我删除了这些命令。 Items 是绑定到 ListView 的集合,ArtifactTypes 是为 ListView 中的对象设置的项的列表。

    [AssociatedView(typeof(ManageImageView))]
public class ManageImagesViewModel : ClosableViewModelBase
{
    private Guid jobid;
    private TSObservableCollection<MobileImage> items = new TSObservableCollection<MobileImage>();
    private TSObservableCollection<ArtifactType> artifactTypes = new TSObservableCollection<ArtifactType>();

    public TSObservableCollection<MobileImage> Items
    {
        get
        {
            return items;
        }
        set
        {
            items = value;
        }
    }
    public TSObservableCollection<ArtifactType> ArtifactTypes
    {
        get
        {
            return artifactTypes;
        }
        set
        {
            if (artifactTypes != value)
                artifactTypes = value;
        }
    }

    public override string Title
    {
        get { return "Add and Delete Images"; }
    }

    public ManageImagesViewModel(IUnityContainer container)
        : base(container)
    {
        AddImage = new SimpleCommand(HandleAddImage);
        UpdateAll = new SimpleCommand(HandleUpdateAll);
        ExitRequest = new SimpleCommand(HandleExitProcess);
        DeleteCommand = new SimpleGenericCommand<Guid>(HandleDeleteProcess);
        List<ArtifactTypeDto> types = BusinessEngine.Mobile.GetTypeDefinitions();
        foreach (ArtifactTypeDto element in types)
        {
            ArtifactTypes.Add(new ArtifactType(element.Name, element.ArtifactTypeId));
        }
    }

还有我的视图定义:

            <ListView Width="510" MinHeight="600" ItemsSource="{Binding Items}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid Margin="4" Height="160" Width="Auto">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="160"/>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="50" />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="42" />
                            <RowDefinition Height="25" />
                            <RowDefinition Height="25" />
                            <RowDefinition Height="25" />
                            <RowDefinition Height="42" />
                        </Grid.RowDefinitions>
                        <Image Source="{Binding Path=Image, Mode=OneWay}" Grid.Column="0" Grid.RowSpan="5" Margin="4" Height="150" Width="150" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                        <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Path=Name, Mode=TwoWay}" FontWeight="Bold" MinWidth="250" FontSize="12"/>
                        <TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Path=Comment, Mode=TwoWay}" FontSize="12" />
                        <ComboBox Grid.Column="1" Grid.Row="3" ItemsSource="{Binding ArtifactTypes, Mode=OneTime}" DisplayMemberPath="Name" SelectedValuePath="Key" SelectedValue="{Binding Path=ArtifactTypeIdentity, Mode=TwoWay}" FontSize="12"/>
                        <Button Grid.Column="2" Grid.Row="1" Command="{Binding DeleteCommand}" CommandParameter="{Binding Path=ArtifactIdentity}">
                            <Button.Content>
                                <Image Margin="5,0,0,0" Height="24" Width="24" VerticalAlignment="Center" HorizontalAlignment="Center" Source="pack://application:,,,/SERVPRO.WorkCenter.Common.UI;component/Images/DeleteRed.png"/>
                            </Button.Content>
                        </Button>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListView>

最后——这是用于填充组合框的值的定义:

    public class ArtifactType:INotifyPropertyChanged
{

    public ArtifactType(string name, Guid value)
    {
        this.Name = name;
        this.Key = value;
    }

    private string name;
    private Guid key;

    public string Name
    {
        get { return name; }
        set
        {
            if (name != value)
            {
                name = value;
                NotifyPropertyChanged("Name");
            }
        }
    }

    public Guid Key
    {
        get { return key; }
        set 
        {
            if (key != value)
            {
                key = value;
                NotifyPropertyChanged("Key");
            }
        }
    }

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

    public event PropertyChangedEventHandler PropertyChanged;
}

那么有人在我的绑定中看到为什么我得到一个空白的组合框列表吗? (TSObservableCollection 是我们的线程安全的 ObservableCollection,用于在不在 UI 线程上但通知 UI 更改时处理更新集合。)

【问题讨论】:

  • 如果在 ItemsSource 绑定中添加 PresentationTraceSources.TraceLevel=High 会说明什么?否则我看不出问题。你确定你没有在视图模型中重置 ArtifactTypes 吗?如果您不使用它,请删除 ArtifactTypes 的设置器,否则请在此处添加 PropertyChanged 通知。尝试使用snoop 查找您的用户界面中的问题。
  • 感谢 Rachel,但我了解 MVVM 的基础知识。它只是解决了数据来源的两个层次结构。那么你什么时候搬到纳什维尔和我结婚? :)

标签: c# .net wpf mvvm


【解决方案1】:

如果您在 Visual Studio 中运行时查看“输出”窗口,您应该会看到存在绑定错误。

您设置绑定的方式是寻找 ArtifactTypes 作为 Items 的属性,而不是您的 ViewModel,因为它是 Items 定义的 ItemTemplate 的一部分。

试试这样的:

ItemsSource="{Binding DataContext.ArtifactTypes, Mode=OneTime, 
              RelativeSource={RelativeSource AncestorType={x:Type ListView}}}"

这样做是将 ItemsSource 绑定到 ListView 的 DataContext 的 ArtifactTypes 属性。那个 DataContext 就是你的 ViewModel。

【讨论】:

  • Wonko the Sane -- 我爱你的名字!!!我认为 ListView 源和 DataContext 源之间存在混淆,真的不知道如何解决它!太感谢了。就像在吱吱作响的铰链上的鼻涕一样工作。 :)
  • 是的 - 绑定可能是讨厌的小动物
猜你喜欢
  • 1970-01-01
  • 2018-07-27
  • 2011-08-05
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
  • 1970-01-01
  • 2016-09-26
相关资源
最近更新 更多