我已经创建了一个基于MVVM的示例 主窗口XAML:
<Window x:Class="LearnMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:LearnMVVM"
xmlns:System="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<Window.Resources>
<ObjectDataProvider x:Key="operationTypeEnum" MethodName="GetValues" ObjectType="{x:Type System:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:OperationType"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<DataTemplate DataType="{x:Type local:SomeUserControlViewModel}">
<local:SomeUserControl />
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="25"/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="25"/>
<RowDefinition />
</Grid.RowDefinitions>
<TextBox Grid.Column="0" Grid.Row="0" Margin="2" Text="{Binding Path=A, Mode=TwoWay}"/>
<TextBlock Grid.Column="1" Grid.Row="0" Text="+" TextAlignment="Center" VerticalAlignment="Center" Height="16" Margin="0,4,0,5"/>
<TextBox Grid.Column="2" Grid.Row="0" Margin="2" Text="{Binding Path=B, Mode=TwoWay}"/>
<Button Grid.Column="3" Grid.Row="0" Margin="2" Content="Посчитать" Command="{Binding ClickCommand}"/>
<TextBox Grid.Column="4" Grid.Row="0" Margin="2" IsReadOnly="True" Text="{Binding Path=Summa, Mode=TwoWay}"/>
<ComboBox Grid.Column="2" Grid.Row="1" SelectedItem="{Binding Path=SomeUserControl.Operation, Mode=TwoWay}" ItemsSource="{Binding Source={StaticResource operationTypeEnum}}" />
<ContentControl Grid.Column="2" Grid.Row="2" BorderThickness="3" BorderBrush="Black" Content="{Binding Path=SomeUserControl}" />
</Grid>
</Window>
SomeUserControl的XAML:
<UserControl x:Class="LearnMVVM.SomeUserControl"
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:learnMvvm="clr-namespace:LearnMVVM"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<learnMvvm:SomeUserControlViewModel />
</UserControl.DataContext>
<DockPanel>
<TextBox DockPanel.Dock="Top" Margin="10" Text="{Binding Path=A, Mode=TwoWay, diag:PresentationTraceSources.TraceLevel=High}" />
<Label DockPanel.Dock="Top" Content="{Binding Path=Operation, diag:PresentationTraceSources.TraceLevel=High}" />
<TextBox DockPanel.Dock="Top" Margin="10" Text="{Binding Path=B, Mode=TwoWay, diag:PresentationTraceSources.TraceLevel=High}" />
<Button DockPanel.Dock="Top" Content="=" Margin="20" Command="{Binding CalculateOperationComamnd, Mode=TwoWay, diag:PresentationTraceSources.TraceLevel=High}" />
<Label DockPanel.Dock="Top" Margin="10" Content="{Binding Path=Result, diag:PresentationTraceSources.TraceLevel=High}" />
</DockPanel>
</UserControl>
SomeCustomUserControl的ViewModel:
using System;
using System.ComponentModel;
using System.Windows.Input;
namespace LearnMVVM
{
public enum OperationType
{
Sum,
Sub,
Div,
Mul
}
public class SomeUserControlViewModel : INotifyPropertyChanged
{
public double A { get; set; }
public double B { get; set; }
//Команды
private ICommand calculateOperationCommand;
public ICommand CalculateOperationComamnd
{
get
{
return calculateOperationCommand;
}
set
{
if (calculateOperationCommand != value)
{
calculateOperationCommand = value;
OnPropertyChanged("CalculateOperationComamnd");
}
}
}
private OperationType operation;
public OperationType Operation
{
get
{
return operation;
}
set
{
if (operation != value)
{
operation = value;
switch (operation)
{
case OperationType.Sum:
CalculateOperationComamnd = new RelayCommand(arg => OperationSum());
break;
case OperationType.Sub:
CalculateOperationComamnd = new RelayCommand(arg => OperationSub());
break;
case OperationType.Div:
CalculateOperationComamnd = new RelayCommand(arg => OperationDiv());
break;
case OperationType.Mul:
CalculateOperationComamnd = new RelayCommand(arg => OperationMul());
break;
}
OnPropertyChanged("Operation");
}
}
}
private void OperationSum()
{
Result = A + B;
}
private void OperationSub()
{
Result = A - B;
}
private void OperationDiv()
{
Result = A/B;
}
private void OperationMul()
{
Result = A*B;
}
private double result;
public double Result
{
get { return result; }
set
{
if (Math.Abs(result - value) > 0.0001)
{
result = value;
OnPropertyChanged("Result");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
问题:当我从组合框中更改所选项目并且&#34;计算按钮无效时,自定义控件不会更改。
实际上,SomeCustomControlViewModel中的所有属性都按预期更新,但在主窗口中没有任何效果。
我错过了什么吗?
答案 0 :(得分:2)
framelayout.post(new Runnable() {
@Override
public void run() {
original = getBitmap();
if (original != null) {
//where exception occurs
setBitmap(original);
}
}
});
private void setBitmap(Bitmap original) {
Bitmap scaledBitmap = scaledBitmap(original, sourceFrame.getWidth(), frameLayout.getHeight());
sourceImageView.setImageBitmap(scaledBitmap);
Bitmap tempBitmap = ((BitmapDrawable) frameLayout.getDrawable()).getBitmap();
Map<Integer, PointF> pointFs = getEdgePoints(tempBitmap);
polygonView.setPoints(pointFs);
polygonView.setVisibility(View.VISIBLE);
int padding = (int) getResources().getDimension(R.dimen.scanPadding);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(tempBitmap.getWidth() + 2 * padding, tempBitmap.getHeight() + 2 * padding);
layoutParams.gravity = Gravity.CENTER;
polygonView.setLayoutParams(layoutParams);
}
private Bitmap scaledBitmap(Bitmap bitmap, int width, int height) {
Matrix m = new Matrix();
//dimensions are always greater than 0 when an image is picked
//but still throws exception
System.out.println("bitmap height: "+bitmap.getHeight());
System.out.println("bitmap Width: "+bitmap.getWidth());
m.setRectToRect(new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()), new RectF(0, 0, width, height), Matrix.ScaleToFit.CENTER);
//exception occurs here
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
}
不是Operation
的属性。它是SomeUserControl
的视图模型的属性 - 可作为控件SomeUserControl
访问。尝试绑定DataContext
,如下所示:
ComboBox.SelectedItem
更改是我在路径中添加了SelectedItem="{Binding Path=SomeUserControl.DataContext.Operation, Mode=TwoWay}"
。
这就是为什么你不使用自定义控件的视图模型,如果你真的想将它们用作控件。您编写一个派生自DataContext
的控件类,并为其提供依赖项属性。 Control
应该是从Operation
派生的类的依赖项属性,而不是viewmodel上的通知属性。然后,您可以通过默认Control
应用ControlTemplate
来为其定义UI。
你在这里得到的是一个真正的儿童视角模特。使用这种类型的安排,通常父视图模型将提供子视图模型的实例,并将其绑定到子控件本身。然后,任何想要使用子视图模型的属性的人都会绑定Style
。