簡體   English   中英

如果Binding為NULL,則Datagrid中的WPF ComboBox會引發錯誤

[英]WPF ComboBox in Datagrid throws error if Binding is NULL

我有一個要編輯的DataGrid。 一列是組合框

<DataGrid ItemsSource="{Binding Persons, Mode=TwoWay}"
          SelectedItem="{Binding SelectedPerson, Mode=TwoWay}" >
     <DataGrid.Columns>
         <DataGridTemplateColumn Header="Company" >
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Companies}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Company.Name}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

問題是,如果公司為null那么我會收到錯誤消息

雙向綁定需要Path或XPath

我如何解決這個問題,以允許將Company設置為null?

Text="{Binding Company.Name}"始終要求Company為有效對象,因為系統最終希望訪問Name屬性。 我仍然希望您可以創建一個虛擬Company對象並將Name設置為空字符串。 否則,轉換器將幫助:

<DataGrid ItemsSource="{Binding Persons, Mode=TwoWay}"
      SelectedItem="{Binding SelectedPerson, Mode=TwoWay}" >
    <DataGrid.Resources>
        <local:MyConverter x:Key="MyConverter"/>
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTemplateColumn Header="Company" >
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Companies}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Company, Converter={StaticResource MyConverter}}" />
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>


public class MyConverter : IValueConverter
{
    public object Convert (object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return string.Empty;
        }

        Type myType = value.GetType ();
        PropertyInfo pinfo = myType.GetProperty ("Name");

        if (pinfo == null)
        {
            return string.Empty;
        }

        return (string)pinfo.GetValue(value);
    }

    public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture)
    {
        return null;
    }
}

轉換器使用反射來訪問Name屬性。 如果轉換器可以訪問Company類型(並且邏輯允許),那么您當然可以直接使用。

該問題已經有了正確的答案,因此這只是快速跟進。 讓我們假設一個演示ViewModel:

public MyViewModel()
{
    CompanyType companyA = new CompanyType();
    companyA.Name = "Comp. A";
    CompanyType companyB = new CompanyType();
    companyB.Name = "Comp. B";
    Companies.Add(companyA);
    Companies.Add(companyB);
    PersonType person1 = new PersonType();
    person1.Id = 1;
    person1.Company = null;
    PersonType person2 = new PersonType();
    person2.Id = 2;
    person2.Company = companyB;
    persons.Add(person1);
    persons.Add(person2);
}

現在,在ComboBox中不起作用的是,在從ComboBox中選擇了另一個公司的新值之后,它並沒有在更改Person's Company的值:在演示中,我們想將person1和2都分配給來自用戶界面。

此外,如果我們不將ComboBox的SelectedItem綁定到PersonType的Company屬性, 則不在person2的ComboBox中選擇CompanyB。

在這里,您可以找到針對組合框Xaml的修復程序

                <DataTemplate>
                    <ComboBox
                        DisplayMemberPath="Name"
                        SelectedValuePath="Name"
                        SelectedItem="{Binding Company}"
                        ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}, Path=DataContext.Companies}"/>
                </DataTemplate>

我的演示課程

public class PersonType // don't need to notify below
{
    public int Id { get; set; }
    public CompanyType Company { get; set; }
}
public class CompanyType
{
    public string Name { get; set; }
}

請注意 ,由於Combobox SelectedItem的綁定,person2的開頭選擇了ComboBox項目CompanyB,現在可以將其Company更改為CompanyA。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM