WinForms 앱에 WPF ElementHost
이 있습니다. 사용자 정의 컨트롤에는 응용 프로그램에서 제공하는 사용 가능한 명령 트리가 표시되어야하는 텍스트와 TreeView
이 있습니다..Net 4 ElementHost (MVVM)의 WPF Cotrol에 바인딩
저는 WPF에 익숙하지 않습니다. (이것은 학습용이므로) 데이터 바인딩에 문제가 있습니다.
CommandTreeViewModel
클래스를 내보기 모델로 사용하도록 만들었습니다. IEnumerable(of CommandViewModel)
인 FirstGeneration
속성이 있습니다. CommandViewModel
클래스는 Children
속성 (다시 IEnumerable(of CommandViewModel)
)을 포함하여 Command
을 설명하는 몇 가지 간단한 속성을 갖습니다.
내 winforms 앱에서 설정 한 WPF User Control에 Public Property ViewModel As CommandTreeViewModel
을 추가했습니다.
어떻게 해야할지 모르겠지만 ViewModel 속성에 전달 된 데이터를 가져 와서 TreeView에 바인딩합니다. (그리고 XAML 바인딩의 ViewModel 클래스 a-la MVC를 강력하게 입력 할 수있는 방법이 있습니까?)
필자는 필요한 경우 아래 관련 코드라는 것을 포함 시켰습니다. 당신이 볼 수 있듯이
사용자 컨트롤
Public Class WPFCommandTree
Implements INotifyPropertyChanged
Public Property ViewModel As CommandTreeViewModel
Get
Return DirectCast(GetValue(ViewModelProperty), CommandTreeViewModel)
End Get
Set(ByVal value As CommandTreeViewModel)
If Not value.Equals(DirectCast(GetValue(ViewModelProperty), CommandTreeViewModel)) Then
SetValue(ViewModelProperty, value)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("ViewModelProperty"))
End If
End Set
End Property
Public Shared ReadOnly ViewModelProperty As DependencyProperty = _
DependencyProperty.Register("ViewModel",
GetType(CommandTreeViewModel), GetType(Window),
New FrameworkPropertyMetadata(Nothing))
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class
XAML
<UserControl x:Class="WPFCommandTree"
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"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock FontSize="30" HorizontalAlignment="Center" VerticalAlignment="Center">Test</TextBlock>
<TreeView ItemsSource="{Binding FirstGeneration}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Grid.Row="1"
DataContext="{Binding}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded"
Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected"
Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="FontWeight"
Value="Normal" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Grid>
</UserControl>
보기 모델
Public Class CommandTreeViewModel
Public Property RootCommand As CommandViewModel
Public Property FirstGeneration As ReadOnlyCollection(Of CommandViewModel)
Public Sub New(ByVal RootCommand As Command)
_RootCommand = New CommandViewModel(RootCommand)
_FirstGeneration = New ReadOnlyCollection(Of CommandViewModel)(New CommandViewModel() {_RootCommand})
End Sub
Public Sub New(ByVal RootCommand As CommandViewModel)
Me.RootCommand = RootCommand
Me.FirstGeneration = New ReadOnlyCollection(Of CommandViewModel)(New CommandViewModel() {_RootCommand})
End Sub
Public Sub New(ByVal RootCommands As IEnumerable(Of CommandViewModel))
Me.RootCommand = RootCommands.First
Me.FirstGeneration = New ReadOnlyCollection(Of CommandViewModel)(RootCommands.ToList)
End Sub
End Class
Public Class CommandViewModel
Implements INotifyPropertyChanged
Public Property Command As Command
Public Property Children As ReadOnlyCollection(Of CommandViewModel)
Public Property Parent As CommandViewModel
Public Property Name As String
Private Property _IsSelected As Boolean
Public Property IsSelected() As Boolean
Get
Return _isSelected
End Get
Set(ByVal value As Boolean)
If value <> _isSelected Then
_isSelected = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("IsSelected"))
End If
End Set
End Property
Private Property _IsExpanded As Boolean
Public Property IsExpanded() As Boolean
Get
Return _IsExpanded
End Get
Set(ByVal value As Boolean)
If value <> IsExpanded Then
_IsExpanded = value
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("IsExpanded"))
If _IsExpanded And _Parent IsNot Nothing Then
_Parent.IsExpanded = True
End If
End If
End Set
End Property
Public Sub New(ByVal Command As Command)
Me.New(Command, Nothing)
End Sub
Private Sub New(ByVal Command As Command, ByVal Parent As CommandViewModel)
_Command = Command
_Parent = Parent
If Command.Children IsNot Nothing AndAlso Command.Children.Count > 0 Then
_Children = New ReadOnlyCollection(Of CommandViewModel)(
Command.Children.Select(Function(x) New CommandViewModel(x, Me)
).ToList)
End If
End Sub
Public Event PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class
, 나는 R 아니에요 내가해야 할 일에 대해 명확하게 설명하고 여러 자습서에서 일부 코드를 함께 해킹하려고 시도했습니다. 대부분은 WPF 만 있습니다.
위를 실행하면 정확하게 양식이로드되지만 양식에 '테스트'텍스트가 표시됩니다. TreeView
은 비어 있습니다. 오류가 발생하지 않습니다. 데이터를 올바르게 바인딩하지 않았기 때문에 이것이라고 가정합니다.
마지막으로 DP가되어야 할 부동산 중 어느 것이 불분명합니까? ViewModel, Model Children? 나는 구속력이 어떻게 작용하는지 명확하지 않다.
감사합니다. XAML은 거의 그대로 복사되었으므로 거기에 불필요한 복잡성이 있다는 것을 알고 있습니다. 디버깅하는 동안이를 고려하는 것을 잊었습니다. 'MyBase.DataContext'가 필요한 것 같습니다. 나는 지금 놀거야. 정말 좋은 팁을 가져 주셔서 감사합니다. – Basic
그건 잘못된 바인딩 명령, 특히'DataContext = "{Binding}"대신'DataContext = "{Binding FirstGeneration}"에 비틀 거렸다. 당신의 도움을 주셔서 감사합니다! – Basic
문제 없습니다, 지금 당장 옳은 길을 걷고 있습니다. –