36

誰でも次のことを手伝ってもらえますか-これで遊んでいますが、私の人生ではそれを機能させることはできません.

次のプロパティを含むビュー モデルがあります。

public ObservableCollection<Rule> Rules { get; set; }
public Rule SelectedRule { get; set; }

私の XAML には、次のようなものがあります。

<ListBox x:Name="lbRules" ItemsSource="{Binding Path=Rules}" 
         SelectedItem="{Binding Path=SelectedRule, Mode=TwoWay}">
<ListBox.ItemTemplate>
    <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Name:" />
                <TextBox x:Name="ruleName">
                    <TextBox.Text>
                        <Binding Path="Name" UpdateSourceTrigger="PropertyChanged" />
                    </TextBox.Text>
                </TextBox>
            </StackPanel>
    </DataTemplate>
</ListBox.ItemTemplate>

これで、ItemsSource が正常に動作し、lbRules に名前が表示された Rule オブジェクトのリストが取得されます。

私が抱えている問題は、SelectedRule プロパティを lbRules の SelectedItem にバインドすることです。テキストブロックのテキスト プロパティを SelectedRule にバインドしようとしましたが、常に null です。

<TextBlock Text="{Binding Path=SelectedRule.Name}" />

出力ウィンドウに表示されるエラー: BindingExpression パス エラー: 'SelectedRule' プロパティが見つかりません。

誰でもこのバインディングを手伝ってもらえますか? SelectedRule プロパティが見つからない理由がわかりません。

次に、テキストブロックのテキスト プロパティを以下のように変更してみました。問題は、ViewModel で SelectedRule を使用したいことです。

<TextBlock Text="{Binding ElementName=lbRules, Path=SelectedItem.Name}" />

どうもありがとうございました。

4

6 に答える 6

27

INotifyPropertyChangedまず、ビュー モデルにインターフェイスを実装PropertyChangedし、プロパティのセッターでイベントを発生させる必要がありRuleます。そうしないと、プロパティにバインドするコントロールは、SelectedRuleいつ変更されたかを「認識」しません。

次に、XAML

<TextBlock Text="{Binding Path=SelectedRule.Name}" />

これがのTextBlock外側にあり、 と同じである場合、 は完全に有効です。ListBoxItemTemplateDataContextListBox

于 2010-01-06T14:10:37.983 に答える
13

DataTemplateのコンテキストで作業している の内部ではRule、 にバインドできないため、SelectedRule.NameにはそのようなプロパティはありませんRule。元のデータ コンテキスト (ViewModel) にバインドするには、次のように記述できます。

<TextBlock Text="{Binding ElementName=lbRules, Path=DataContext.SelectedRule.Name}" />

更新: SelectedItem プロパティのバインドに関しては、完全に有効に見えます。マシンで同じことを試してみましたが、正常に動作します。ここに私の完全なテストアプリがあります:

XAML:

<Window x:Class="TestWpfApplication.ListBoxSelectedItem"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="ListBoxSelectedItem" Height="300" Width="300"
    xmlns:app="clr-namespace:TestWpfApplication">
    <Window.DataContext>
        <app:ListBoxSelectedItemViewModel/>
    </Window.DataContext>
    <ListBox ItemsSource="{Binding Path=Rules}" SelectedItem="{Binding Path=SelectedRule, Mode=TwoWay}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Name:" />
                    <TextBox Text="{Binding Name}"/>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Window>

コードビハインド:

namespace TestWpfApplication
{
    /// <summary>
    /// Interaction logic for ListBoxSelectedItem.xaml
    /// </summary>
    public partial class ListBoxSelectedItem : Window
    {
        public ListBoxSelectedItem()
        {
            InitializeComponent();
        }
    }


    public class Rule
    {
        public string Name { get; set; }
    }

    public class ListBoxSelectedItemViewModel
    {
        public ListBoxSelectedItemViewModel()
        {
            Rules = new ObservableCollection<Rule>()
            {
                new Rule() { Name = "Rule 1"},
                new Rule() { Name = "Rule 2"},
                new Rule() { Name = "Rule 3"},
            };
        }

        public ObservableCollection<Rule> Rules { get; private set; }

        private Rule selectedRule;
        public Rule SelectedRule
        {
            get { return selectedRule; }
            set
            {
                selectedRule = value;
            }
        }
    }
}
于 2010-01-06T11:26:27.830 に答える
3

ヨコーダーは正しい、

内ではDataTemplate、現在の処理DataContextに設定されています。Rule

親にアクセスするには、バインディングでDataContexta を使用することも検討できます。RelativeSource

<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ____Your Parent control here___ }}, Path=DataContext.SelectedRule.Name}" />

詳細については、次を参照しRelativeSourceてください。

http://msdn.microsoft.com/en-us/library/system.windows.data.relativesource.aspx

于 2010-01-06T11:32:05.530 に答える
0

私は通常DataContext、この質問のような 2 つの深さのプロパティをバインドするために一緒に使用します。

<TextBlock DataContext="{Binding SelectedRule}" Text="{Binding Name}" />

または、ElementNameビュー コントロールのみでバインディングを実現するため、使用することを好みます。

<TextBlock DataContext="{Binding ElementName=lbRules, Path=SelectedItem}" Text="{Binding Name}" />

于 2015-08-05T14:54:08.067 に答える
-7

itemsourceをコレクションに設定するため、テキストボックスはそのコレクション内の個々のアイテムに関連付けられます。選択したアイテムプロパティは、2つのリストボックスを持つマスター/詳細フォームを実行しようとした場合にこのシナリオで役立ちます。2番目のリストボックスのitemsourceをルールの子コレクションにバインドします。言い換えると、選択されたアイテムは、ソースが変更されたことをコントロールの外部に警告します。内部コントロール(データテンプレート内のコントロールはすでに変更を認識しています)。

ほとんどの場合、質問に「はい」と答えるには、itemsourceを設定することは、コントロールのdatacontextを設定することと同じです。

于 2010-01-06T12:12:30.097 に答える