【发布时间】:2019-11-30 09:05:49
【问题描述】:
我有一组已绑定到 WPF DataGrid 的项目。其中一列需要允许用户从枚举中进行选择。我还创建了一个单独的类来为每个枚举值保存用户友好的显示字符串。
这些是类型:
public enum UnitEnum { Metres, Hours, SingleValue };
public class UnitTuple
{
public UnitEnum Unit { get; set; }
public string DisplayName { get; set; }
}
public class CostItem
{
public string Name { get; set; }
public UnitEnum UnitID { get; set; }
}
这是我的视图模型:
public static List<UnitTuple> AllUnitTuples = new List<UnitTuple>()
{
new UnitTuple { Unit = UnitEnum.Metres, DisplayName = "Metres" },
new UnitTuple { Unit = UnitEnum.Hours, DisplayName = "Hours" },
new UnitTuple { Unit = UnitEnum.SingleValue, DisplayName = "Single Value" }
};
public List<CostItem> CostItems => new List<CostItem>()
{
new CostItem() { Name = "Design", UnitID = UnitEnum.SingleValue },
new CostItem() { Name = "Manufacturing", UnitID = UnitEnum.Hours },
new CostItem() { Name = "Materials", UnitID = UnitEnum.Metres }
};
这是我正在使用的 XAML 的开始:
<DataGrid x:Name="DataGridCostItems"
ItemsSource="{Binding CostItems}"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Cost Item Name" Binding="{Binding Name}"/>
<DataGridComboBoxColumn Header="Units"/>
</DataGrid.Columns>
</DataGrid>
谁能帮我解决剩下的数据绑定表达式(例如ItemsSource、SelectedValueBinding)?
我一直在尝试遵循下面显示的两个示例,但在将这些示例映射到我的代码时遇到了麻烦。
根据 Aakanksha 的回答,我试图让 ObjectDataProvider 工作但不能。我遇到的问题——DataGridComboBoxColumn 显然没有视图模型的数据上下文——在这里解释:Cannot find governing FrameworkElement。
同一篇文章建议改用CollectionViewSource。尝试这个解决方案导致下面的代码几乎可以工作:组合框列正确填充了用户友好的显示字符串,当我选择一个进行编辑时,我得到一个包含用户友好显示字符串的下拉列表为枚举。都很好。
我现在唯一无法终生工作的部分是让组合框中新选择的值保持回数据绑定的CostItem。
谁能建议如何解决最后一个难题?
public enum CostUnit
{
SingleValue,
Hours,
Metres
}
public class CostUnitTuple
{
public EstimateCostUnitTuple( EstimateCostUnit enumValue, string displayString )
{
EnumValue = enumValue;
DisplayString = displayString;
}
public CostUnit EnumValue { get; private set; }
public string DisplayString { get; private set; };
}
public static class CostUnitAllTuples
{
public static string GetDisplayStringFromEnum( CostUnit enumValue ) { ... }
public static CostUnit GetEnumFromDisplayString( string displayString ) { ... }
public static CostUnitTuple[] GetValues => new CostUnitTuple[]
{
new CostUnitTuple( CostUnit.Hours, "Hours" ),
new CostUnitTuple( CostUnit.Metres, "Metres" ),
new CostUnitTuple( CostUnit.SingleValue, "Single Value" )
};
}
public class CostItem
{
public string Name { get; set; } = "";
public CostUnit Units
{
get => _units;
set
{
_units = value;
UnitDisplayString = CostUnitAllTuples.GetDisplayStringFromEnum( _units );
}
}
public string UnitDisplayString { get; private set; } = "";
private CostUnit _units;
}
public class UnitsOfMeasureConverter : IValueConverter
{
public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) =>
CostUnitAllTuples.GetDisplayStringFromEnum( (CostUnit)value );
public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) =>
((EstimateCostUnitTuple)value).EnumValue;
}
public class ViewModel
{
public List<CostItem> CostItems { get; set; }
public AllCostUnits => CostUnitAllTuples.GetValues;
}
<Control.Resources>
<ResourceDictionary>
<u:UnitsOfMeasureConverter x:Key="UnitsOfMeasureConverterKey"/>
<CollectionViewSource x:Key="UnitsCollectionViewSourceKey" Source="{Binding AllCostUnits}"/>
</ResourceDictionary>
</Control.Resources>
<DataGrid
ItemsSource="{Binding CostItems}"
SelectionMode="Single">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridComboBoxColumn Header="Units"
TextBinding="{Binding UnitDisplayString,Mode=OneWay}"
SelectedItemBinding="{Binding Units,Converter={StaticResource UnitsOfMeasureConverterKey}}"
DisplayMemberPath="DisplayString"
ItemsSource="{Binding Source={StaticResource UnitsCollectionViewSourceKey}}"/>
</DataGrid.Columns>
</DataGrid>
【问题讨论】:
标签: wpf xaml data-binding datagrid