4

ポップアップとテキストビューを組み合わせた単純なユーザーコントロールを作成していますが、おかしなことは何もありません。最初にウィンドウに設定してすべてのスタイルを設定したときは完全に機能しましたが、実際に仕上げるためにユーザー コントロールに移動すると、正しく機能しなくなりました。

最小値と最大値をコントロールに渡すと、その範囲から選択する数値のリストが自動的に作成されます。ユーザー コントロールでは、数字のリストが正しくバインドされません。その理由は誰にもわかりません。誰かが私のコードを見てくれるかもしれません。

これに関する他の質問をたくさん読みましたが、実際に何が起こっているのかわかりません。出力ウィンドウにエラーが表示されないため、手がかりはありません。とにかく、ここにコードがあります -

UserControl.xaml

<UserControl x:Class="UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         x:Name="Me"
         DataContext="{Binding RelativeSource={RelativeSource Self}}">

<StackPanel>
    <TextBox Name="myTextbox"
             Height="30"
             Margin="0"
             FontSize="14"
             IsReadOnly="True"
             Padding="5,2"
             Text="{Binding Value}" />
    <Popup x:Name="myPopup"
           PlacementTarget="{Binding ElementName=myTextbox}"
           StaysOpen="True">
        <Popup.Style>
            <Style TargetType="{x:Type Popup}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=myTextbox, Path=IsFocused}" Value="True">
                        <Setter Property="IsOpen" Value="True" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Popup.Style>

        <StackPanel>
            <ListView Name="myListView"
                      Height="100"
                      MaxHeight="300"
                      ItemsSource="{Binding List,
                                            UpdateSourceTrigger=PropertyChanged}"
                      SelectionChanged="ListView_SelectionChanged">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Label Width="100"
                               Height="30"
                               Margin="0"
                               Content="{Binding}"
                               FontFamily="Segoe UI"
                               FontSize="14"
                               Padding="5,2" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <Button Width="200" Height="30" />
        </StackPanel>
    </Popup>

</StackPanel>

UserControl.xaml.vb

Imports System.ComponentModel
Imports System.Linq.Expressions
Imports System.Collections.ObjectModel

Class UserControl1

' Dependency Properties
Public Shared ReadOnly ListProperty As DependencyProperty = DependencyProperty.Register("List", GetType(ObservableCollection(Of Integer)), GetType(MainWindow))
Public Shared ReadOnly ValueProperty As DependencyProperty = DependencyProperty.Register("Value", GetType(Integer), GetType(MainWindow))
Public Shared ReadOnly MaxValueProperty As DependencyProperty = DependencyProperty.Register("MaxValue", GetType(Integer), GetType(MainWindow))
Public Shared ReadOnly MinValueProperty As DependencyProperty = DependencyProperty.Register("MinValue", GetType(Integer), GetType(MainWindow))

' Properties
Public Property List As ObservableCollection(Of Integer)
    Get
        Return DirectCast(GetValue(ListProperty), ObservableCollection(Of Integer))
    End Get
    Set(value As ObservableCollection(Of Integer))
        SetValue(ListProperty, value)
    End Set
End Property

Public Property Value As Integer
    Get
        Return DirectCast(GetValue(ValueProperty), Integer)
    End Get
    Set(value As Integer)
        SetValue(ValueProperty, value)

    End Set
End Property

Public Property MaxValue As Integer
    Get
        Return DirectCast(GetValue(MaxValueProperty), Integer)
    End Get
    Set(value As Integer)
        SetValue(MaxValueProperty, value)
    End Set
End Property

Public Property MinValue As Integer
    Get
        Return DirectCast(GetValue(MinValueProperty), Integer)
    End Get
    Set(value As Integer)
        SetValue(MinValueProperty, value)
    End Set
End Property

Private Sub ListView_SelectionChanged(sender As System.Object, e As System.Windows.Controls.SelectionChangedEventArgs)
    Value = List(myListView.SelectedIndex)
End Sub

Private Sub UserControl1_Loaded(sender As Object, e As System.Windows.RoutedEventArgs) Handles Me.Loaded
    List = New ObservableCollection(Of Integer)

    ' Add all available numbers into the list
    For iCounter As Integer = MinValue To MaxValue
        List.Add(iCounter)
    Next

    ' Set the selected index on the list for the value
    myListView.SelectedIndex = Value - MinValue
End Sub
End Class

参考までに、これをテストしたとき、ウィンドウとユーザーコントロールの両方のセットアップで最小値と最大値を自分で設定しました。

4

3 に答える 3

17

私が最初に WPF を学び始めたときと同じ過ちを犯したと思います。これがあなたの問題の原因であるとは断言できませんが、私が確認できる唯一の問題であるため、対処します。UserControl.DataContext残念ながら、 aをそれ自体に接続する方法を示す貧弱なチュートリアルと簡単な例が非常に多くあります。

DataContext="{Binding RelativeSource={RelativeSource Self}}"

または:

DataContext = this;

コード ビハインドで定義されたプロパティにすばやく簡単に接続できるため、外部にアクセスしたくない場合は、これで問題ありません。ただし、コントロールの外部からプロパティにアクセスしたい場合は、問題が発生します。これらの場合 (すべての場合ではないにしても)、コード ビハインド プロパティに to を使用する必要があります。BindUserControlBindRelativeSource BindingBind

<TextBox Name="myTextbox" Height="30" Margin="0" FontSize="14" IsReadOnly="True"
    Padding="5,2" Text="{Binding Value, RelativeSource={RelativeSource AncestorType={
    x:Type UserControl1}}}" />

このBindingでは、プロパティを宣言したUserControl1の名前です。UserControlこれは、すべての内部 で実行する必要がありますBinding。このように、DataContextはに設定されませんUserControlが、 はBinding引き続きプロパティを見つけます。

詳細についてRelativeSourceは、MSDN のRelativeSource MarkupExtensionページを参照してください。

于 2013-10-05T14:50:53.480 に答える
9

シェリダンに良い答えを提供できないので、新しい答えを提供する必要があります。申し訳ありません。

私はこのソリューションが大好きですが、

DataContext="{Binding RelativeSource={RelativeSource Self}}"

(シェリダンがすでに指摘したように)すぐに失敗します。

あなたができることは、ユーザーコントロールのコンテンツの DataContext を設定することです

<UserControl x:Class="Example.View.Controls.MyUserControl"
         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:controls="clr-namespace:Example.View.Controls"
         mc:Ignorable="d">
<Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type controls:MyUserControl}}}">

</Grid>

このように、コード ビハインドから DP に直接バインドできるため、次のすべてのバインディングのボイラープレート コードが少なくなります。

<Label Content="{Binding MyLabel}"/>
于 2014-12-11T18:12:37.260 に答える
1

Windows アプリ (Windows 8 および Windows 10 UWP)の場合は、コントロールに名前を付け、 PathElementNameを使用して XAML ファイル内で参照します。

<UserControl
x:Class="MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="Control"
mc:Ignorable="d" >

   <Grid Height="240" VerticalAlignment="Top">
     <Rectangle Fill="{Binding ElementName=Control, Path=Background}" />
   </Grid>
</UserControl>

``

于 2015-11-11T13:43:24.187 に答える