在我的UserControl ucStep2中,我有Step2InfoData对象的DataContext,它具有以下几个属性:
private string rockDensUnit;
public string RockDensity_Unit
{
get { return rockDensUnit; }
set
{
if (rockDensUnit != value)
{
rockDensUnit = value;
Changed("RockDensity_Unit");
}
}
}
在我的应用程序中,我需要使用不同的常规测量类型绑定几个组合,例如{kg / m3,gm / m3},{meter,cm}等等这些测量组。我的意思是,多个组合可以列出相同的项目。所以我更喜欢创建可以在多个组合中使用的类列表。我创建了ComboItems.cs,其中包含填充下拉列表所需的所有项目列表。
ComboItems.cs
//**OBJECTS I USE FOR LIST OF IEMS**
// Class for kg, gm
public class KgGmItems
{
public ObservableCollection<string> KgGmList { get; set; }
public KgGmItems()
{
KgGmList = new ObservableCollection<string>();
KgGmList.Add("kg/m3");
KgGmList.Add("gram/cm3");
}
public string ValueSelected { get; set; } // Don't know if this is useful in my case
}
// Class for meter, cm
public class MtCmItems : INotifyPropertyChanged
{
public MtCmItems()
{
Dict = new Dictionary<string, string>
{
{"meter", "meter"},
{"centimeter", "centimeter"}
};
}
//...
}
XML即ucStep2查看
<!-- As the objects KgGmItems doesn't contain in ucStep2.xaml.cs or Step2InfoData (that is bound to this UC) so add reference of those classes -->
<UserControl.Resources>
<ObjectDataProvider x:Key="KgGmObj" ObjectType="{x:Type top:KgGmItems}" />
<ObjectDataProvider x:Key="MtCmObj" ObjectType="{x:Type top:MtCmItems}" />
</UserControl.Resources>
<ComboBox DataContext="{StaticResource KgGmObj}" ItemsSource="{Binding KgGmList}" SelectedValue="{Binding Path=RockDensity_Unit, Mode=TwoWay}" SelectedIndex="0"
Background="#FFB7B39D" Grid.Row="5" Height="23" HorizontalAlignment="Left" Margin="401,61,0,0" Name="comboBox6" VerticalAlignment="Top" Width="84" Visibility="Hidden">
</ComboBox>
我想从KgGmItems类中显示ObservableCllection KgGmList项,并将所选值绑定到绑定到此UserControl的类Step2InfoData的RockDensity_Unit。
在上面的组合中,我可以显示下拉菜单中的所有项目,默认情况下也会选择第一项。但是这个值并没有绑定到RockDensity_Unit;它的值仍为空。
我希望双向发生这种情况,即当以编程方式设置RockDensity_Unit proeprtiy的值时,应在下拉列表中选择该值。当然,值应该存在于列表中。
默认情况下,应选择第一项。
更新 在ucStep2.xaml.cs中添加了DependencyProperty
public static readonly DependencyProperty RockDensityUnitProperty =
DependencyProperty.Register("RockDensity_Unit", typeof(string), typeof(UserControl),
new FrameworkPropertyMetadata("kg/m3", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public string RockDensity_Unit
{
get { return this.GetValue(RockDensityUnitProperty) as string; }
set { SetValue(RockDensityUnitProperty, value); }
}
XML
<ComboBox DataContext="{StaticResource KgGmObj}" ItemsSource="{Binding KgGmList}" SelectedItem="{Binding Path=RockDensity_Unit, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ucStep2}}, Mode=TwoWay}"
Background="#FFB7B39D" Grid.Row="5" Height="23" HorizontalAlignment="Left" Margin="401,61,0,0" Name="comboBox6" VerticalAlignment="Top" Width="84" Visibility="Hidden">
</ComboBox>
错误
错误1类型引用找不到名为“ucStep2”的公共类型。第74行位置194.这是指组合框“,” 在FindAncestor之后
DOUBT Step2InfoData中的RockDensity_Unit CLR属性未受影响。
为什么代码无法找到ucStep2?仅供参考,我认为这可能是相关的:
<UserControl x:Class="WellBore.ucStep2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WellBore.Models"
xmlns:top="clr-namespace:WellBore"
mc:Ignorable="d"
d:DesignHeight="870" d:DesignWidth="700" MaxHeight="970" MinHeight="700" MaxWidth="600">
答案 0 :(得分:1)
使用字典。
XAML
<ComboBox ItemsSource="{Binding Dict}"
DisplayMemberPath="Value"
SelectedValuePath="Key"
SelectedValue="{Binding Prop}"/>
背后的代码
public Dictionary< ValueType, string > Dict { get; private set; }
private ValueType _prop;
public ValueType Prop
{
get{ return _prop }
set
{
_prop = value;
NotifyPropertyChanged( "Prop" ); // Implement INotifyPropertyChanged
}
}
public ViewModel()
{
Dict = new Dictionary< ValueType, string >()
{
{ value1, string1 },
{ value2, string2 },
{ value3, string3 }
};
}
答案 1 :(得分:1)
好的,让我们让这个绑定工作......首先,我使用KgGmItems
类中的一个项目绑定到ComboBox
。在这个类中,您有一组string
值显示在下拉列表中,string
属性绑定到ComboBox.SelectedItem
...完美!现在我假设你在名为Resources
的{{1}}部分中有一个这个类的实例...让我们保持简单开头:
KgGmObj
这就是您在<ComboBox DataContext="{StaticResource KgGmObj}" ItemsSource="{Binding KgGmList}"
SelectedItem="{Binding ValueSelected, Mode=TwoWay}" />
和您的班级之间设置绑定所需的全部内容。但有一点需要注意的是,当您尝试从代码中设置所选项目时,如果将其设置为集合中的某个实际项目,它将仅工作...我认为使用ComboBox
时这并不重要,但无论如何都要知道这一点很重要。如果您将自定义类设置为string
中的对象类型,则可以设置所选项目,如下所示:
ComboBox
如果你有一个独特的可识别财产,那就更好了:
ValueSelected = KgGmList.Where(item => item.Name == "NameOfObjectToMatch").Single();
使用ValueSelected = KgGmList.Where(item => item.Id == Id).Single()
值,您应该能够从以下代码中设置所选项目:
string
更新&gt;&gt;&gt;好吧,让我们再来一次......我想我可能现在有足够的信息继续下去。我想你想要这样的东西:
ValueSelected = "Some value";
问题在于您已将<ComboBox DataContext="{StaticResource KgGmObj}" ItemsSource="{Binding KgGmList}"
SelectedItem="{Binding RockDensity_Unit, Mode=TwoWay}" />
的{{1}}设置为DataContext
个对象。这意味着框架将尝试在该对象中找到名为ComboBox
的属性。我还看到了你对这个属性的定义中的另一个潜在问题。
要从KgGmObj
xaml绑定到其后面的代码,您需要使用RockDensity_Unit
。您可以从MSDN的Dependency Properties Overview页面了解如何实现这些功能。首先,我建议您将UserControl
属性实现为DependencyProperty
。
接下来,我们必须从xaml中的RockDensity_Unit
找到该属性的方法...我们可以使用DependencyProperty
这样的绑定来实现:
ComboBox
现在,如果你有一个RelativeSource
绑定到<ComboBox DataContext="{StaticResource KgGmObj}" ItemsSource="{Binding KgGmList}"
SelectedItem="{Binding RockDensity_Unit, RelativeSource={RelativeSource Mode=
FindAncestor, AncestorType={x:Type ucStep2}}, Mode=TwoWay}" />
属性,而你的DependencyProperty
类名为SelectedItem
,那么这一切都可以工作......让我知道怎么回事。
更新2&gt;&gt;&gt;
您的错误是因为您必须在XAML文件的顶部添加XML命名空间......如下所示:
UserControl
然后你用它来引用你的类:
ucStep2
此外,在您的xmlns:YourNamespace="clr-namespace:ApplicationName.FolderNameContainingClass"
声明中,您应该提供您的控件的类型,而不是...AncestorType={x:Type YourNamespace:ucStep2} ...
,因此请更改
DependencyProperty
到
UserControl
显然......将'NameOfYourUserControl'替换为扩展Register("RockDensity_Unit", typeof(string), typeof(UserControl),
的类的实际名称。