0

私の 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 にバインドされていません。その値は null のままです。

これを双方向で実現したい。つまり、RockDensity_Unit プロパティの値がプログラムで設定されている場合、ドロップダウンで値を選択する必要があります。もちろん、値はリストに存在する必要があります。

デフォルトでは、最初の項目が選択されているはずです。

更新 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' という名前のパブリック タイプを見つけることができません。Line 74 Position 194. これは、FindAncestor の後のコンボボックス ", " を指します。

疑問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">
4

2 に答える 2

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 }
    };
}
于 2013-08-28T17:12:54.097 に答える
1

では、このバインディングを機能させましょう...まず、KgGmItemsクラスのアイテムを使用してComboBox. このクラスにはstring、ドロップダウンに表示する値のコレクションと、それにstringバインドするプロパティがありComboBox.SelectedItemます...完璧です! ここで、 ...というResourcesセクションにこのクラスのインスタンスがあると仮定しています。KgGmObj

<ComboBox DataContext="{StaticResource KgGmObj}" ItemsSource="{Binding KgGmList}" 
SelectedItem="{Binding ValueSelected, Mode=TwoWay}" />

ComboBoxとクラスの間のバインディングをセットアップするために必要なのはこれだけです。ただし、コードから選択したアイテムを設定しようとすると、コレクション内の実際のアイテムの1つに設定した場合にのみ機能することに注意してください...これは実際にはカウントされないと思いますsを使用しstringていますが、とにかくこれを知ることが重要です。代わりにオブジェクトのタイプとしてカスタム クラスを設定している場合はComboBox、選択した項目を次のように設定できます。

ValueSelected = KgGmList.Where(item => item.Name == "NameOfObjectToMatch").Single();

または、一意に識別可能なプロパティがある場合は、次のようにすることをお勧めします。

ValueSelected = KgGmList.Where(item => item.Id == Id).Single()

string値を使用すると、次のようなコードから選択した項目を設定できるはずです。

ValueSelected = "Some value";

更新 >>> では、もう一度始めましょう... これで十分な情報が得られ思います。私はあなたがこのようなものが欲しいと思います:

<ComboBox DataContext="{StaticResource KgGmObj}" ItemsSource="{Binding KgGmList}" 
SelectedItem="{Binding RockDensity_Unit, Mode=TwoWay}" />

これに関する問題は、DataContextComboBoxKgGmObjオブジェクトに設定したことです。RockDensity_Unit これは、フレームワークがその object で指定されたプロパティを見つけようとすることを意味します。このプロパティの定義には、別の潜在的な問題もあります。

UserControlxaml からそのコード ビハインドにバインドするには、 DependencyProperty. これらを実装する方法については、MSDNの依存関係プロパティの概要ページを参照してください。まず、RockDensity_Unitプロパティを として実装することをお勧めしますDependencyProperty

次に、xaml でそのプロパティへの方法を見つける必要がComboBoxあります...次のRelativeSourceようなバインディングを使用してそれを行うことができます。

<ComboBox DataContext="{StaticResource KgGmObj}" ItemsSource="{Binding KgGmList}" 
SelectedItem="{Binding RockDensity_Unit, RelativeSource={RelativeSource Mode=
FindAncestor, AncestorType={x:Type ucStep2}}, Mode=TwoWay}" />

さて、プロパティDependencyPropertyにバインドする必要があり、クラスの名前がである場合、これはすべて機能するはずです...どうなるか教えてください。SelectedItemUserControlucStep2

更新 2 >>>

あなたのエラーは、XAML ファイルの先頭に XML 名前空間を追加する必要があるためです...次のようなものです:

xmlns:YourNamespace="clr-namespace:ApplicationName.FolderNameContainingClass"

次に、それを使用して、次のようにクラスを参照します。

...AncestorType={x:Type YourNamespace:ucStep2} ...

また、宣言ではコントロールDependencyPropertyのタイプではなく名前を指定する必要があるため、変更しますUserControl

Register("RockDensity_Unit", typeof(string), typeof(UserControl),

Register("RockDensity_Unit", typeof(string), typeof(NameOfYourUserControl),

明らかに...「NameOfYourUserControl」を、を拡張するクラスの実際の名前に置き換えますUserControl

于 2013-08-29T13:12:30.697 に答える